java-线程之间的协作
一、线程之间的协作:join()
class JoinExample{ private class A extends Thread{ @Override public void run(){ System.out.println("A"); } } private class B extends Thread{ private A a; B(A a){ this.a = a; } @Override public void run(){ try { // 在B线程中调用了A的join()方法,b会等待a线程结束才继续执行 a.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("B"); } } public void m1(){ A a = new A(); B b = new B(a); b.start(); a.start(); } public static void main(String[] args) { JoinExample joinExample = new JoinExample(); joinExample.m1(); } }
>>>输出:
A
B
二、线程之间的协作:wait()、notify()、notifyAll()
/**
* 线程之间的协作:wait()、notify()、notifyAll(),它们都属于Object的一部分,不属于Thread。只能在同步方法/块中使用
* wait()和sleep()的区别:wait()是Object的方法,sleep()是Thread的静态方法。wait()会释放锁,sleep()不会释放锁
*/
class WaitNotifyExample{ public synchronized void m1(){ System.out.println("m1 output"); notify(); } public synchronized void m2(){ try { // 使用wait(),线程在等待时被挂起,直到其他线程调用notify()或notifyAll()后才会唤醒挂起的线程 // wait()挂起期间,线程会释放锁。因为如果未释放锁其他线程就无法进入对象的同步方法/块中,就无法执行notify()来唤醒挂起的线程,造成死锁 wait(); System.out.println("m2 output"); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); WaitNotifyExample waitNotifyExample = new WaitNotifyExample(); executorService.execute(waitNotifyExample::m2); executorService.execute(waitNotifyExample::m1); executorService.shutdown(); } }
>>>输出:
m1 output
m2 output
三、线程之间的协作:await()、signal()、signalAll(),属于J.U.C的Condition类。相比于wait(),await()可以指定等待的条件
class AwaitSignalExample{ private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void m1(){ lock.lock(); try { System.out.println("before"); condition.signal(); } finally { lock.unlock(); } } public void m2(){ lock.lock(); try { // 在Condition上使用await()使线程等待,其他线程调用signal()或signalAll()唤醒等待的线程 condition.await(); System.out.println("after"); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } } public static void main(String[] args) { AwaitSignalExample awaitSignalExample = new AwaitSignalExample(); ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(awaitSignalExample::m2); executorService.execute(awaitSignalExample::m1); executorService.shutdown(); } }
>>>输出:
before
after