一、问题定义
运行10个线程,按照顺序打印0123456789,Java代码实现!
二、具体实现
1、原始实现
设定一个orderNum,每个线程执行结束后,更新orderNum,指明下一个要执行的线程,并且唤醒所有的等待线程;在每一个线程的开始,要while判断orderNum是否等于自己的要求值,不是则wait,是则执行本线程。
public class OrderedThread extends Thread {
private int id;
private static int flag = 0;
public OrderedThread(int id) {
this.id = id;
}
@Override
public void run() {
while (flag != id){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("%s thread run, id is %s\n", Thread.currentThread().getName(), id);
synchronized (OrderedThread.class){
flag++;
}
}
public static void main(String[] args) {
OrderedThread[] orderedThreads = new OrderedThread[10];
for (int i = 0; i < 10; i++) {
orderedThreads[i] = new OrderedThread(i);
orderedThreads[i].start();
}
}
}
2、使用join方法
使用join方法,让当前执行线程等待直到调用join()方法的线程结束运行,join()方法的主要作用是同步,使得线程之间的并行执行变为串行执行。
public class OrderedThreadUsingJoin extends Thread {
private int id;
public OrderedThreadUsingJoin(int id) {
this.id = id;
}
@Override
public void run() {
System.out.printf("%s thread run, id is %s\n", Thread.currentThread().getName(), id);
}
public static void main(String[] args) throws InterruptedException {
OrderedThreadUsingJoin[] orderedThreadUsingJoins = new OrderedThreadUsingJoin[10];
for (int i = 0; i < 10; i++) {
orderedThreadUsingJoins[i] = new OrderedThreadUsingJoin(i);
orderedThreadUsingJoins[i].start();
/*
程序在main线程中调用orderedThreadUsingJoins[i]线程的join方法,则main线程放弃cpu控制权,并返回
orderedThreadUsingJoins[i]线程继续执行直到线程orderedThreadUsingJoins[i]执行完毕,然后到主线程执行,相当于
在main线程中同步orderedThreadUsingJoins[i]线程,orderedThreadUsingJoins[i]执行完了,main线程才有执行的机会
*/
orderedThreadUsingJoins[i].join();
}
}
}
注意:这里是main线程循环和orderedThreadUsingJoins[i]线程同步,因为所有子线程都是从main线程中启动的,这样就达到了顺序串行打印的目的!此外,join()的调用要在start()之后,不然无法起到同步的作用!
3、使用单线程池
使用单线程池,这样就能根据传入的顺序执行线程。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OrderedThreadsUsingThreadPool extends Thread{
private int id;
public OrderedThreadsUsingThreadPool(int id) {
this.id = id;
}
@Override
public void run() {
System.out.printf("%s thread run, id is %s\n", Thread.currentThread().getName(), id);
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
OrderedThreadsUsingThreadPool[] orderedThreadsUsingThreadPools = new OrderedThreadsUsingThreadPool[10];
for (int i = 0; i < 10; i++) {
orderedThreadsUsingThreadPools[i] = new OrderedThreadsUsingThreadPool(i);
executorService.execute(orderedThreadsUsingThreadPools[i]);
}
}
}