package com.gxnyt.util;
/**
* 啓用三個線程-依次打印出1-100;
* 思路:使用wait,notify+信號量(即聲明的一個被同步鎖-鎖住的對象)
* 有一個小坑: 在最後一個100打印時,不要再讓線程進入wait()狀態;
* 因爲沒有別的線程可以再喚醒它;會一直處在wait()狀態;而程序掛起;
* Created by Zjt_WuLing on 2019/9/22.
*/
public class MultiThreadDemo {
static Object lockObj = new Object();
static volatile int printInt = 1;
//聲明一個對象,做爲被鎖的對象;
// 由同步鎖來對該對象上鎖;
// 在某一線程佔有該對象時,判斷是否可以打印(滿足條件),不能打印則釋放該對象(wait方法),同時通知需要該對象的其它線程(notifyAll-喚醒其它線程->進入就緒狀態)
public static void main(String[] args) {
Thread threadFirst = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lockObj) {
while (printInt <= 100) {
if (printInt % 3 == 1) {
System.out.println("threadName" + Thread.currentThread().getName() + ";i===" + printInt++);
}
lockObj.notifyAll();
if (printInt == 101) {//這裏是個小坑;最後一次不執行wait()方法
return;
}
try {
lockObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread threadSecond = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lockObj) {
while (printInt <= 100) {
if (printInt % 3 == 2) {
System.out.println("threadName" + Thread.currentThread().getName() + ";i===" + printInt++);
}
lockObj.notifyAll();
try {
lockObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread threadThird = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lockObj) {
while (printInt <= 100) {
if (printInt % 3 == 0) {
System.out.println("threadName" + Thread.currentThread().getName() + ";i===" + printInt++);
}
lockObj.notifyAll();
try {
lockObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
threadFirst.start();
threadSecond.start();
threadThird.start();
}
}
關於線程的五種狀態如上圖;