首先我們先看一下多線程開發的口訣:
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();
}
}