首先我们先看一下多线程开发的口诀:
1、高内聚低耦合的前提下,多线程操作资源类
2、判断/干活/通知
3、判断一定要使用while,不能使用if。使用if会出现线程虚假唤醒
4、标识位
下面我们完成一个顺序执行的题目:
/**
* 题目:按顺序执行下面三个线程
* A线程:打印5个数字(第一步)
* B线程:打印5个数字(第二步)
* C线程:打印5个数字(第三步)
*
* 上面三个线程 依次执行,循环10次
*
主要技术点总结:
1、Lock 类似 synchronized
2、Condition 是建立在 Lock上面的,一个Lock对应多个Condition。
Condition可以一个对象的多个等待线程放入不同的等待池里面,通过这种特性
可以精确的唤醒一个线程。
3、Condition必须写在 lock.lock()和lock.unlock()代码之间。执行
condition1.await()的时候,会先释放锁,然后在暂停线程。所以condition一定
是先拥有锁。
*/
class Resource{
//定义标识位: 1 =A , 2 =B , 3 =C
private int num = 1;
//定义一个锁对象
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
public void printA() throws Exception {
lock.lock();
try {
while (num != 1){
condition1.await();
}
for (int i = 1; i <= 5; i++){
System.out.println(Thread.currentThread().getName() + " --- >" + i);
}
num = 2;
condition2.signal();
}finally {
lock.unlock();
}
}
public void printB() throws Exception {
lock.lock();
try {
while(num != 2){
condition2.await();
}
for (int i = 1; i <= 5; i++){
System.out.println(Thread.currentThread().getName() + " --- >" + i);
}
num = 3;
condition3.signal();
}finally {
lock.unlock();
}
}
public void printC() throws Exception {
lock.lock();
try {
while(num != 3){
condition3.await();
}
for (int i = 1; i <= 5; i++){
System.out.println(Thread.currentThread().getName() + " --- >" + i);
}
num = 1;
condition1.signal();
}finally {
lock.unlock();
}
}
}
public class Thread05 {
public static void main(String[] args) {
Resource resource = new Resource();
new Thread( () -> {
try {
for (int i = 1; i <=10; i++){resource.printA();};
} catch (Exception e) {
e.printStackTrace();
}
},"A" ).start();
new Thread( () -> {
try {
for (int i = 1; i <=10; i++){resource.printB();};
} catch (Exception e) {
e.printStackTrace();
}
},"B" ).start();
new Thread( () -> {
try {
for (int i = 1; i <=10; i++){resource.printC();};
} catch (Exception e) {
e.printStackTrace();
}
},"C" ).start();
}
}