首先我們先看一下多線程開發(fā)的口訣:
1、高內(nèi)聚低耦合的前提下,多線程操作資源類
2、判斷/干活/通知
3、判斷一定要使用while,不能使用if。使用if會(huì)出現(xiàn)線程虛假喚醒
4、標(biāo)識(shí)位
下面我們完成一個(gè)順序執(zhí)行的題目:
/**
* 題目:按順序執(zhí)行下面三個(gè)線程
* A線程:打印5個(gè)數(shù)字(第一步)
* B線程:打印5個(gè)數(shù)字(第二步)
* C線程:打印5個(gè)數(shù)字(第三步)
*
* 上面三個(gè)線程 依次執(zhí)行,循環(huán)10次
*
主要技術(shù)點(diǎn)總結(jié):
1、Lock 類似 synchronized
2、Condition 是建立在 Lock上面的,一個(gè)Lock對(duì)應(yīng)多個(gè)Condition。
Condition可以一個(gè)對(duì)象的多個(gè)等待線程放入不同的等待池里面,通過這種特性
可以精確的喚醒一個(gè)線程。
3、Condition必須寫在 lock.lock()和lock.unlock()代碼之間。執(zhí)行
condition1.await()的時(shí)候,會(huì)先釋放鎖,然后在暫停線程。所以condition一定
是先擁有鎖。
*/
class Resource{
//定義標(biāo)識(shí)位: 1 =A , 2 =B , 3 =C
private int num = 1;
//定義一個(gè)鎖對(duì)象
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();
}
}