-
通信
-
4个问题
- 线程间如何传递信息
-
线程之间如何同步
- 以使一个线程的活动不会破坏另一个线程的活动
- 当线程间具有依赖关系时,如何调度多个线程的处理顺序
- 如何避免死锁问题
-
java 3个方法
-
wait()
- 使调用该方法的线程释放共享资源的锁,然后从运行态退出,进入等待队列,直到被再次唤醒
- wait()方法使得当前线程必须要等待,等到另外一个线程调用notify()或者notifyAll()方法。
- 当前的线程必须拥有当前对象的monitor,也即lock,就是锁。
- 线程调用wait()方法,释放它对锁的拥有权,然后等待另外的线程来通知它(通知的方式是notify()或者notifyAll()方法),这样它才能重新获得锁的拥有权和恢复执行。
- 要确保调用wait()方法的时候拥有锁,即,wait()方法的调用必须放在synchronized方法或synchronized块中。
-
一个小比较:Thread.sleep()
- 它会导致线程睡眠指定的毫秒数,但线程在睡眠的过程中是不会释放掉对象的锁的。
-
notify()
- 唤醒等待队列中第一个等待同一共享资源的线程,并使该线程退出等待队列,进入可运行态
- 被唤醒的线程是不能被执行的,需要等到当前线程放弃这个对象的锁。
- 竞争,来获得对象的锁
- notify()方法应该是被拥有对象的锁的线程所调用。
- wait()和notify()方法要求在调用时线程已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或synchronized块中。
-
notifyAll()
- 使所有正在等待队列中等待同一共享资源的线程从等待状态退出,进入可运行状态,此时,优先级最高的那个线程最先执行
- 只有在synchronized关键字作用的范围内,并且是同一个同步问题中搭配使用这3个方法时才有实际的意义
- java.util.concurrent 包
-
共享内存
- 让工作类继承Runable,这样方便多个Thread使用同一个工作类,从而读取同一个工作类的成员变量。
-
java进程
- 调用的是操作系统的进程
- 进程之间的通信需要在内核的环境
-
进程间通信
- 管道
-
系统IPC(Inter-Process Communication,进程间通信)
- 消息队列
- 信号
- 共享存储
- 套接字
-
几个方法
-
sleep()和wait()
- 调用sleep()方法并不会让线程释放它所持有的同步锁;而且在这期间它也不会阻碍其它线程的运行。
-
yield()
- 让当前运行Thread放弃其所占用的cpu时间片,以便让其他Thread运行
- 让Thread能适当地轮转
- 即使当前Thread放弃时间片,可是还有可能再次被JVM选中!也就是连任。
-
join()
- 让当前Thread加入到myThread线程的尾部,意味着myThread线程运行结束之前,当前Thread不会运行。
-
引发死锁四个条件
-
互斥(Mutual exclusion)
- 线程所使用的资源中至少有一个是不能共享的,它在同一时刻只能由一个线程使用。
-
持有与等待(Hold and wait)
- 至少有一个线程已经持有了资源,并且正在等待获取其他的线程所持有的资源。
-
非抢占式(No pre-emption)
- 如果一个线程已经持有了某个资源,那么在这个线程释放这个资源之前,别的线程不能把它抢夺过去使用。
- 循环等待(Circular wait)