一、线程之间的协作:join()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 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()不会释放锁
*/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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()可以指定等待的条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步