您的位置:首页 > 其它

线程通信

2019-04-25 19:59 106 查看

当线程在系统内运行时,线程调度具有一定的透明性,程序通常无法准确控制线程的轮换执行,但我们可以通过一些机制来保证线程的协调运行。

1、传统的线程通信
假设现在系统中有两个线程,这两个线程分别代表取钱者和存款者-----并且假设系统有一种特殊的要求,系统要求存款者和取钱者不断地重复存钱、取钱的动作,而且要求每当存款者将钱存入指定账户后,取钱者就立即取出这笔钱。

为了实现这种功能,可以借助于Object类提供的wait()、notify()和notifyAll()三个方法,这三个方法属于Object类。但这三个方法必须由同步监视器对象来调用。

  • 对于使用synchronized修饰的同步方法,因为该类的默认实例就是同步监视器,所以可以在同步方法中直接调用这三个方法。
  • 对于使用synchronized修饰的同步代码块,同步监视器是synchronized后括号里的对象,所以必须使用该对象调用这三个方法。

关于这三个方法的解释如下:

  • wait(): 导致该线程等待,直到其他线程调用该同步监视器的notify()方法或notifyAll()方法来唤醒该线程。
  • notify(): 唤醒在此时同步监视器上等待的单个线程。如果所有线程都在此同步监视器上等待,则会唤醒其中一个线程。选择是任意性的。
  • notifyAll(): 唤醒在此同步监视器上等待的所有线程。只有当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程。

2、使用Condition控制线程通信
如果程序不使用synchronized关键字来保证同步,而是直接使用Lock对象来保持同步,则系统中不存在隐式的同步监视器,也就不能使用wait()、notify()、notifyAll()方法进行现场通信了。

当使用Lock对象来保证同步时,Java提供了一个Condition类来保持协调,使用Condition可以让那些已经得到Lock对象却无法继续执行的线程释放Lock对象。在这种情况下,Lock替代了同步方法或同步代码块,Condition替代了同步监视器的功能。

Condition实例被绑定在一个Lock对象上。要获得特定Lock实例的Condition实例,调用Lock对象的newCondition()方法即可。Condition类提供了以下三种方法。

  1. await(): 类似于隐式同步监视器上的wait()方法,导致当前线程等待,直到其他线程调用该Condition的signal()或signalAll()方法来唤醒该线程。
  2. signal():唤醒在此Lock对象上等待的单个线程。
  3. signalAll(): 唤醒在此Lock对象上等待的所有线程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: