-------android培训、java培训、期待与您交流! ----------
线程间通信涉及到的方法:
wait():当前处于运行状态的线程进入等待状态,如果没有唤醒该线程,则其一直处于等待状态。
notify():唤醒第一个进入等待状态的线程。
notifyAll():唤醒线程池中所有的等待状态的线程。
这些方法都是Object对象的 方法,任何对象都含有这些方法。因为要对持有监视器(锁)的线程操作,所以这些方法都使用在同步中,只有同步的时候才具有锁。
为什么这些方法都要定义在Object父类中呢?因为这些方法在操作同步中线程时,都必须要标识它们所操作线程持有的锁,只有在同一个锁上的等待线程可以被同一个锁上的notify方法唤醒。不可以对不同锁上的线程进行唤醒。也就是说线程的等待和被唤醒必须是同一个锁。锁可以是任意的对象。所以可以被定义在Object对象中。
在生产者和消费者的同步问题中,生产者生产一个产品,消费者就应该消费一个产品。其中是具有一一对应的关系的。也就是说生产者生产一个产品以后就应该进入等待状态,等待消费者将产品消费掉。此时消费者就应该进入等待状态,并唤醒生产者,继续等待生产者生产产品。如果使用notify来唤醒,在多个生产者和消费者同时工作的例子中,则没办法保证唤醒的是对方的线程,因为容易出现只唤醒本方线程的情况(生产者唤醒生产者或者消费者唤醒消费者)。所以应该使用notifyAll方法。它能将线程池中的等待线程全部唤醒。此时会有一个问题:如果线程不再进行判断标记,则会出现生产者生产产品后没有被消费,其他生产者就又生产了新的产品。这是与我们实际需求不符的。解决办法:使用while循环判断标记。
while(flag)
try{this.wait();}catch(Exception e){}
notifyAll方法不仅唤醒对方线程,但也同时唤醒了本方的线程,如果我们只想唤醒对方线程该怎么办呢?
JDK1.5以后,有了升级解决方案就是将同步synchronized替换成lock操作。将Object中的wait,notify和notifyAll替换成了Condition对象,该对象可以通过Lock锁的newCondition方法来获取。
如何使线程结束?
在较早之前我们都是使用stop()方法来结束线程,由于这个方法容易引发异常,已被官方列为Deprecated,所以我们将来写程序尽量不要使用该方法来结束进程。
我们知道,当run方法结束执行时,其对应的线程就执行结束了。所以我们可以通过某种方法让run方法执行结束的方式来结束进程。这也是唯一的可以结束线程的方式。另外开启多条线程并发执行时通常都是循环结构,我们只要控制住循环的执行就可以让run方法结束,达到让线程结束执行的目的。但是如果某条线程已经处于了冻结状态,它就没办法读取到标记,那么就无法使得线程结束运行。当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除强制让线程恢复到运行状态,这样就可以操作标记让线程结束。
另一种中断线程的方式:调用Thread类的interrupt()方法。会抛出SecurityException异常。
线程相关的几个方法说明:
join():当某个线程A执行了另一个线程B的join方法时,A线程就会进入等待状态,直到B线程完全执行结束A才会继续执行
setDaemon():将某个线程或多个线程设置成后台线程(守护线程),如果正在运行的线程全部是守护线程时,JVM就会退出。
setPriority():设置线程的优先级,值从1-10.其中1,5,10分别有三个静态常量与之对应,分别是MIN_PRIORITY,NORM_PRIORITY,MAX_PRIORITY。默认为5,一般我们不需要设置这个值。