假設(shè)有3個線程,依次打印A、B、C,按順序循環(huán)打印100次。
這個其實(shí)是線程通信,如果只是按順序執(zhí)行,用只有一個線程的線程池,依次提交線程任務(wù)就行,但是這里還不是每個線程只執(zhí)行一次,需要循環(huán)重復(fù)打印。
這里有兩種處理方式,一種是搞個全局int變量,對線程數(shù)取模,得到0~2,再轉(zhuǎn)ASCII碼。一種是3個線程按照創(chuàng)建時的順序嚴(yán)格執(zhí)行。
第一種思路寫法:
這里只用到了原生的阻塞喚醒方法,線程競爭獲取鎖,確保同時只有一個線程累加countIndex和打印,3個線程的執(zhí)行順序就不是創(chuàng)建的順序,而是隨機(jī)的。文章來源:http://www.zghlxwxcb.cn/news/detail-759701.html
public class ThreeThreadPrintOrderlyBySync {
private static final Object LOCK = new Object();
private static volatile int countIndex = 0;
private static final int MAX = 100;
private static final int WORKER_COUNT = 3;
public static void main(String[] args) {
Thread thread1 = new Thread(new Worker(0));
Thread thread2 = new Thread(new Worker(1));
Thread thread3 = new Thread(new Worker(2));
thread1.start();
thread2.start();
thread3.start();
}
public static class Worker implements Runnable {
private final int index;
public Worker(int index) {
this.index = index;
}
@Override
public void run() {
while (countIndex < MAX) {
synchronized (LOCK) {
try {
if (countIndex % WORKER_COUNT != index) {
LOCK.wait();
}
if (countIndex <= MAX) {
System.out.printf(String.valueOf((char) (65 + countIndex % WORKER_COUNT)));
}
countIndex++;
LOCK.notifyAll();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
第二種處理方式:
通過線程序號控制ReentrantLock中Condition的阻塞喚醒文章來源地址http://www.zghlxwxcb.cn/news/detail-759701.html
public class ThreeThreadPrint {
private static final int WORKER_COUNT = 3;
private static final ReentrantLock LOCK = new ReentrantLock();
private static int countIndex = 0;
public static void main(String[] args) {
List<Condition> conditions = new ArrayList<>();
for (int i = 0; i < WORKER_COUNT; i++) {
Condition condition = LOCK.newCondition();
conditions.add(condition);
Thread thread = new Worker(i, conditions);
thread.start();
}
}
public static class Worker extends Thread {
private int index;
private List<Condition> conditions;
public Worker(int index, List<Condition> conditions) {
super("Thread" + index);
this.index = index;
this.conditions = conditions;
}
@Override
public void run() {
while (true) {
LOCK.lock();
try {
if (countIndex % WORKER_COUNT != index) {
conditions.get(index).await();
}
if (countIndex > 100) {
conditions.get((index + 1) % conditions.size()).signal();
return;
}
System.out.printf(String.valueOf((char) (65 + countIndex % 3)));
countIndex++;
conditions.get((index + 1) % conditions.size()).signal();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
LOCK.unlock();
}
}
}
}
}
到了這里,關(guān)于線程按順序循環(huán)執(zhí)行的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!