了解并发编程
并发编程是Java程序员最重要的技能之一,也是最难掌握的技能之一。很多情况下我们不敢轻易使用,因为不了解其底层原理,很可能踩坑。接下来一段时间就来学习并发编程的底层类源码。
本篇先了解并发编程的基础。
上图是从并发编程的艺术书中摘录。简单解释一下。
当调用Thread.start后,线程进入可运行状态。只等cpu分配时间片啦。
yield()方法后,线程可让出自己,让其他线程先执行,该线程仍可以随时执行。
wait()方法后进入等待状态。让出自己的资源。
当线程synchronized没有获得锁,则进入阻塞状态。
线程执行完成后,进入终止状态。
下面一起来看start方法和wait、notify方法的使用
public class MultiThreadBase {
private static Object res = new Object();
public static void main(String[] args) throws InterruptedException {
final MultiThreadBase multiThreadBase = new MultiThreadBase();
for(int i=0; i< 5; i++) {
new Thread(()-> {
multiThreadBase.testWait();
}).start();
}
TimeUnit.SECONDS.sleep(1L);
System.out.println("---多线程已启动---");
synchronized (res) {
res.notify();
}
TimeUnit.SECONDS.sleep(1L);
System.out.println("---一个线程已被唤醒---");
synchronized (res) {
res.notifyAll();
}
TimeUnit.SECONDS.sleep(1L);
System.out.println("---全部等待线程已被唤醒---");
}
private void testWait() {
synchronized (res) {
System.out.println(Thread.currentThread().getName() + ": start");
try {
res.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": end");
}
}
}
运行结果:
Thread-0: start
Thread-2: start
Thread-1: start
Thread-3: start
Thread-4: start
---多线程已启动---
Thread-0: end
---一个线程已被唤醒---
Thread-4: end
Thread-3: end
Thread-1: end
Thread-2: end
---全部等待线程已被唤醒---
上面代码可以看到
- wait方法使用时应先加锁
- wait方法会释放锁资源(注意这是和Thread.sleep方法不同的)
- notify方法唤醒一个等待该资源的线程
- notifyAll方法唤醒所有等待该资源的线程
private static void testJoin(MultiThreadBase multiThreadBase) throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " testJoin start");
Thread t = new Thread(()-> {
System.out.println(Thread.currentThread().getName() + " start");
try {
TimeUnit.SECONDS.sleep(2L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " end");
});
t.start();
t.join();
System.out.println(Thread.currentThread().getName() + " testJoin end");
}
运行结果:
main testJoin start
Thread-0 start
Thread-0 end
main testJoin end
可以看到当使用join方法后,当前线程会等待目标线程执行完后,才执行后续代码(有兴趣的朋友可以看join方法源码,内部确实是调用wait方法)
并发编程基础方法先介绍到这,下一篇介绍interrupt方法,水平有限,说的不对的地方请大家指出,及时修正