年假前一天看到这么一篇文章:
https://blog.csdn.net/zhoufanyang_china/article/details/86667897#commentsedit
补充如下程序通过N个线程顺序循环打印从0至100,如给定N=3则输出:
thread0: 0
thread1: 1
thread2: 2
thread0: 3
thread1: 4
...
注意线程号与输出顺序间的关系。
是关于一道多线程循环打印的问题,我自己也苦思冥想.奈何自己技术不到位,写的程序为了保证线程顺序执行.用的队列,join,数组.
都无法摆脱死锁的尴尬,后来又认真的看了一遍博主写的,才发现我可能理解错误了,只是顺序打印并不要求线程能够顺序执行.
自己做了修改后如下:
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadQuestion {
private AtomicInteger index = new AtomicInteger(1);
public static void main(String[] args) {
/**
* 这里n代表线程数,可以修改或者录入
*/
int n = 3;
ThreadQuestion threadQuestion = new ThreadQuestion();
threadQuestion.initThread(n);
}
/**
* 初始化线程
* @param n
*/
private void initThread(int n) {
Print print = new Print(n);
for (int i = 1; i <= n; i++) {
new Thread(new MyRunnable(i == n ? 0 : i, print)).start();
}
}
/**
* 最终执行的类
*/
class Print {
int bornNum;
Print(int bornNum) {
this.bornNum = bornNum;
}
synchronized void print(int remainder) {
/**
* 结束最后一次执行
*/
if(index.get()>100){
return;
}
/**
* 这里在notifyAll的时候判断是否匹配当前循环数,匹配打印,不匹配wait.
*/
if (index.get() % bornNum == remainder) {
System.out.println(Thread.currentThread().getName() + ":" + (index.getAndIncrement()-1));
notifyAll();
}else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyRunnable implements Runnable {
private Print print;
private int i;
MyRunnable(int i, Print print) {
this.i=i;
this.print = print;
}
@Override
public void run() {
while (index.get() <=100) {
print.print(i);
}
}
}
}
其实关键在于这里
/**
* 结束最后一次执行
*/
if(index.get()>100){
return;
}
/**
* 这里在notifyAll的时候判断是否匹配当前循环数,匹配打印,不匹配wait.
*/
if (index.get() % bornNum == remainder) {
System.out.println(Thread.currentThread().getName() + ":" + (index.getAndIncrement()-1));
notifyAll();
}else {
当调用notifyAll的时候判断抢占的线程是否匹配当前循环数...匹配则打印,不匹配则wait让出执行权.
当然还有其他的写法,可以参考这篇https://blog.csdn.net/qq_26567507/article/details/82666852;
燃灯朝复夕,渐作长年身。
紫阁未归日,青门又见春。
掩关寒过尽,开定草生新。
自有林中趣,谁惊岁去频。