博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程讲解(七)
阅读量:3958 次
发布时间:2019-05-24

本文共 1965 字,大约阅读时间需要 6 分钟。

线程间通信

线程作为程序内部的多个执行流,相互之间是可以进行通信的.

线程间通信可以通过多种方式来进行,例如:线程间可以通过共享变量进行通信,使每个线程根据共享变量的值进行操作和运算,当通过共享变量进行通信时,通常需要引入线程同步控制;线程间也可以通过wait(),notify()notifyAll()等方法进行通信.

等待集合

等待集合(Wait-sets)就像候车室一样,当线程调用wait()方法发生等待后,都要进入到该等待集合中,除非发生一下情况,否则线程会一直在该等待集合中.

  1. 其他线程调用了方法notify()notifyAll();
  2. 其他线程调用了方法interrupt()中断了该线程;
  3. 方法wait()的等待时间结束.

wait(),notify(),notifyAll()方法

wait(),notify()notifyAll()方法是类Object中定义的方法,由于Java中的类都是Object类中的子类,因此在Java语言中任何类的对象都可以调用这些方法,但这些方法更多的是在多线程环境中使用.

wait()方法

wait()方法调用的一般形式:

对象名.wait()
称作线程在对象上的等待,作用是把当前线程放入对象的等待集合中.
很多情况下,都是在当前对象上调用wait()方法,即this.wait(),而this又可以省去,所以只有一个wait()来表示等待,表示在当前对象上等待.
wait()方法通常需要放入以synchronized()方法修饰的语句块或方法中,如果在synchronized外调用wait()方法,运行时刻Java虚拟机会抛出IllegalMonitorException异常.
当线程调用wait()方法后,Java虚拟机会让当前线程进入到休眠状态,并释放对象的同步锁的控制权,允许其他线程执行同步代码块,要唤醒该线程,需要在一个对象上调用notify()notifyAll()方法.

notify()方法

线程不能一直待在等待集合中,必须有方法对其进行唤醒notify()方法可以对线程进行唤醒.

当调用某个对象的notify()方法时,将从该对象等待集合中选择一个等待的线程唤醒,唤醒的线程将从等待集合中删除.

notifyAll()方法

notifyAll()方法会将所有在等待集合中的线程唤醒,但由于所有被唤醒的线程仍然要去争用synchronized锁,而synchronized锁具有排他性,最终只有一个线程获得该锁,进入执行状态,其他的线程仍然要继续等待.

条件变量

线程进入临界区后,往往需要等待某个条件满足才能继续执行.如:消费者需要等待缓冲区有产品后才能消费.

从JDK1.5版本开始引入了条件变量(ConditionVariables).条件变量也被称为条件队列(ConditionQueues),是由接口Condition定义的,它可以让一个线程在条件不满足的情况下一直等待,直到有其他线程唤醒它.

接口Condition与JDK1.5版本之前的wait(),notify()notifyAll()方法操作有以下4个不同:

  1. 它允许在一个对象上有多个等待集合.
  2. 当synchronized锁被Lock锁对象替换后,相应的对象监视器方法也要用await(),signal()signalAll()方法操作替代.
  3. Condition对象与在对象监视器上的方法wait(),notify()notifyAll()的行为和语义不同.Condition对象在唤醒线程的次序上与对象监视上的方法不同,并且唤醒时不要求一定持有Lock对象锁.
  4. Condition接口的实例有一个对象,在synchronized控制访问内,可以在Condition对象实例上调用方法wait(),notify()notifyAll().

由于要对共享状态进行操作,所以Condition对象一般是要包含在同步操作中,Lock对象为Condition提供了这种同步操作.Condition对象通常被绑定到Lock对象上,要创建一个Condition对象实例,须要Lock的方法newCondition().

await()方法

调用await()方法之前,当前线程应该持有与此Condition相关联的锁,否则会抛出IllegalMonitorStateException异常.

signal()方法

signal()方法用于唤醒一个正在等待的线程.如果调用了此方法,则在当前条件对象上等待的线程中选择一个线程进行唤醒.

signalAll()方法

signalAll()方法用于唤醒所有正在等待的线程.如果调用了此方法,则在当前条件对象上等待的所有线程都将唤醒.

转载地址:http://tyazi.baihongyu.com/

你可能感兴趣的文章
杭电ACM——1789,Doing Homework Again(贪心)
查看>>
北大ACM——2782,Bin Packing(贪心)
查看>>
北大ACM——4014,Dice(贪心)
查看>>
杭电ACM——4864,Task(贪心)
查看>>
北大ACM——3176,Cow Bowling(动态规划)
查看>>
北大ACM——2229,Sumsets(DP或思维)
查看>>
北大ACM——3186,Treats For The Cows(DP)
查看>>
杭电ACM——蝎子搬新家(贪心)
查看>>
杭电ACM——处理木棍(贪心)
查看>>
杭电ACM——broomstick训练营(贪心)
查看>>
杭电ACM——1018,Big Number(思维)
查看>>
杭电ACM——6463(思维)
查看>>
杭电AC——6561(思维)
查看>>
杭电ACM——1034,Candy Sharing Game
查看>>
杭电ACM——建房子(贪心)
查看>>
杭电ACM——1297,Children’s Queue(递推)
查看>>
杭电ACM——1003,Max Sum(DP)
查看>>
杭电ACM——1042,N!(思维)
查看>>
杭电ACM——1060,Leftmost Digit(思维)
查看>>
杭电ACM——1061,Rightmost Digit(思维)
查看>>