线程间的通信(六)

程序是操作系统中的独立个体,但是个体如果不经过特殊处理就不能称为一个整体通信,线程间的通信就成为整体的必用方式之一,当线程存在通信指挥,系统间的交互性会更强大,在提高CPU利用率的同时还会使开发人员对线程任务在处理的过程中进行有效的把控与监督。


wait/notify/notifyAll

1.wait,释放锁,之后的代码不执行,进入阻塞(暂停)状态。

2.wait的作用是使当前执行代码的线程进行等待, wait方法是 Object类的方法,该方法用来将当前线程置入“预执行队列”中,并且在 wait所在的代码行处停止执行,直到接到通知或被中断为止。

3.在调用 wait之前,线程必须获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait方法。在执行wait方法后,当前线程释放锁。在从wait返回前,线程与其他线程竞争重新获得锁。如果调用 wait时没有持有适当的锁,则抛出异常,它是 RuntimeException的一个子类,因此,不需要try catch语句进行捕捉异常。


notify  
    
1.方法 notify(也要在同步方法或同步块中调用,即在调用前,线程也必须获得该对象的对象级别锁。如果调用 notify时没有持有适当的锁,也会抛出 IllegalMonitorState Exception。该方法用来通知那些可能等待该对象的对象锁的其他线程,如果有多个线程等待,则由线程规划器随机挑选出其中一个呈wait状态的线程,对其发出通知 notify,并使它等待获取该对象的对象锁。

2.在执行notfiy方法后,当前线程不会马上释放该对象锁,呈wait状态的线程也并不能马上获取该对象锁,要等到执行 notify方法的线程将程序执行完,也就是退出 synchronized代码块后,当前线程才会释放锁,而呈wait状态所在的线程才可以获取该对象锁。

3.当第一个获得了该对象锁的wait线程运行完毕以后,它会释放掉该对象锁,此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,还会继续阻塞在wait状态,直到这个对象发出一个notify或 notifyAll。


总结

1.wait使线程停止运行,而 notify使停止的线程继续运行。

2.wait方法可以使调用该方法的线程释放共享资源的锁,然后从运行状态退出,进入等待队列,直到被再次唤醒。

3.notify方法可以随机唤醒等待队列中等待同一共享资源的“一个”线程,并使该线程退出等待队列,进入可运行状态,也就是 notify方法仅通知“一个”线程。

4.notifyAll方法可以使所有正在等待队列中等待同一共享资源的“全部”线程从等待状态退出,进入可运行状态。此时,优先级最高的那个线程最先执行,但也有可能是随机执行,因为这要取决于JVM虚拟机的实现。

5.方法Wait(锁释放与 notify()锁不释放当方法 wait被执行后,锁被自动释放,但执行完 notify方法,锁却不自动释放。必须执行完 notify方法所在的同步 synchronized代码块后才释放锁。得到锁的线程不会立即运行,变成运行态。


方法join的使用

在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束。这时,如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据中的值,就要用到 join方法了。方法join的作用是等待线程对象销毁。

 

public static void main(String[] args) {  
        try {  
            MyThread threadtest = new MyThread();  
            threadtest.start();  
            threadtest.join();  
            System.out.println("我想当 threadtest对象执行完毕后我再执行,我做到了");  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }

方法join的作用是使所属的线程对象x正常执行runO方法中的任务,而使当前线程z进行无限期的阻塞,等待线程x销毁后再继续执行线程z后面的代码。方法join具有使线程排队运行的作用,有些类似同步的运行效果。

join与synchronized的区别是:join在内部使用wait方法进行等待,而 sychronized关键字使用的是“对象监器”原理做为同步。

方法join(long)与sleep(long)的区别

方法join(long)的功能在内部是使用wait(long)方法来实现的,所以join(long)方法具有释放锁的特点。从源代码中可以了解到,当执行 wait(long)方法后,当前线程的锁被释放,那么其他线程就可以调用此线程中的同步方法了。而 Thread. sleep(long)方法却不释放锁。

猜你喜欢

转载自blog.csdn.net/u014401141/article/details/79147703