今天小编继续来分享下多线程中的一些内容。
在多线程环境下,由于线程调度的不确定性,所以我们有时候无法很好的去保证其线程的执行顺序。
但是呢,我们又要实现这个顺序执行,所以我们可以使用到这两个方法,wait 和 notify
当然,这两个方法是要在锁内部进行调用的。
那wait 和 notify 方法是什么呢?
wait
是使当前执行代码的线程进行等待。它还具有另一个带参数的版本:wait(long timeout)
这里的等待,会放进一个等待队列中。
然后,接着会释放当前代码锁的资源
当满足一定的条件过后,它会被唤醒,重新去获取锁。
那这里的条件呢,有这些:
1.其他线程进行notify()
2.当带参数的版本中,时间超出了long timeout,也会被唤醒
3.其他线程中,调用本线程的interrupted方法,导致了wait抛出InterruptedException异常
notify
这个方法是唤醒等待的线程。
这里要值得注意的是
1.notify需要在同步方法或者同步块中使用,因为该方法是去通知可能等待该对象的对象锁的其他线程,并使它们重新获取锁资源。
同步方法:是指synchronized关键字修饰的方法。
同步块:
synchronized(锁){
}
2.如若是多个线程进行等待,那么此时唤醒线程,也是随机的,没有所谓的“先来后到之说”
3.notify方法执行完后,不会立即释放当前锁资源,而是还会等到同步方法,或者同步块执行完。
那来看看这个例子,是如何搭配一起使用的吧
public static void main(String[] args) throws InterruptedException {Object obj=new Object();Thread t=new Thread(()->{synchronized (obj){System.out.println("notify之前");obj.notify();System.out.println("notify之后");}});System.out.println("wait之前");synchronized(obj){t.start();obj.wait();}System.out.println("wait之后");}
代码结果如下:
wait之前
notify之前
notify之后
wait之后
ok,再次引入一个例子,加深对其的了解吧
比如,我现在要按顺序打印A、B、C
那么我们该如何做呢?
我们可以创建三个线程,两个锁
A线程,打印A,B线程中等待,C等待B线程
打印完A,那就唤醒B线程
打印完B线程,然后去唤醒C线程。
代码如下:
public class Demo21 {public static Object locker=new Object();public static Object locker2=new Object();public static void main(String[] args) throws InterruptedException {Thread A=new Thread(()->{System.out.println("A");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (locker){locker.notify();}});Thread B=new Thread(()->{synchronized (locker){try {locker.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("B");}synchronized (locker2){locker2.notify();}});Thread C=new Thread(()->{synchronized (locker2){try {locker2.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("C");}});A.start();B.start();C.start();}
}
那么,除了这个notify,还有一个notifyAll
那么这个notifyAll又是什么呢?
notifyAll
notifyAll方法可以一次性唤醒所有的线程等待。
这里值得注意的是,notifyAll多次调用是没有问题,不会出现报错
还有,这个是需要同一把锁,才能全部唤醒
唤醒后,所有线程需要重新获取锁,获取锁的过程是系统决定,依然是具有不确定性。
ok,那么小编就先分享到这里吧。