目錄
1、使用場景
在實際項目之中可能會要求執行多個線程;並且要求線程能夠按照指定的順序進行執行。網上搜索了好幾篇文章,看完之後自己總結一下以備不時之需。並且可能在面試的過程之中會提問相關的問題。
2、多個線程順序執行的實現方法
2.1、原子類型實現線程順序執行
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicOrderTask implements Runnable {
private AtomicInteger count;
private int order;
public AtomicOrderTask(AtomicInteger count, int order) {
this.count = count;
this.order = order;
}
@Override
public void run(){
/*
while (true) {
}
*/
if (count.get() % 3 == order) {
System.out.println(Thread.currentThread().getName() + " ===== "+ order);
System.out.println("count: "+count);
count.incrementAndGet();
//System.out.println("count.get(): "+count.get());
}
}
}
public class ThreadOrder {
private static AtomicInteger count =new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
atomicIntegerThreadOrder();//使用原子類型實現線程順序執行
//volatileThreadOrder();//使用 volatile變量實現線程順序執行
//joinMethodThreadOrder(); //線程的join方法實現線程順序執行
//threadExecutorSubmitOrder();//使用線程池的submit方法實現線程順序執行
}
/**
* 使用原子類型實現線程順序執行
* @throws InterruptedException
*/
public static void atomicIntegerThreadOrder() throws InterruptedException{
AtomicOrderTask task1 = new AtomicOrderTask(count, 0);
AtomicOrderTask task2 = new AtomicOrderTask(count, 1);
AtomicOrderTask task3 = new AtomicOrderTask(count, 2);
Thread thread1 = new Thread(task1);
Thread thread2 = new Thread(task2);
Thread thread3 = new Thread(task3);
thread1.setDaemon(true);
thread2.setDaemon(true);
thread3.setDaemon(true);
thread1.start();
thread2.start();
thread3.start();
Thread.sleep(1 * 1000);
//每次執行完畢後重新清0
if (count.get()==3){
count =new AtomicInteger(0);
}
}
}
執行效果
2.2、volatile變量實現線程順序執行
public class Holder {
volatile int count = 0;
}
import java.util.concurrent.atomic.AtomicInteger;
public class VolatileOrderTask implements Runnable {
private Holder holder;
private int order;
public VolatileOrderTask(Holder holder, int order) {
this.holder = holder;
this.order = order;
}
@Override
public void run(){
if (holder.count % 3 == order) {
System.out.println(Thread.currentThread().getName() + " ===== "+ order);
System.out.println("holder.count: "+order);
holder.count ++;
}
}
}
/**
* 測試線程有序執行
* 使用共享變量的方式:代碼如下
* 利用原子遞增控制線程准入順序
*/
public class ThreadOrder {
private static AtomicInteger count =new AtomicInteger(0);
private static Holder holder = new Holder();
public static void main(String[] args) throws InterruptedException {
//atomicIntegerThreadOrder();//使用原子類型實現線程順序執行
volatileThreadOrder();//使用 volatile變量實現線程順序執行
//joinMethodThreadOrder(); //線程的join方法實現線程順序執行
//threadExecutorSubmitOrder();//使用線程池的submit方法實現線程順序執行
}
/**
*volatile變量在各個線程中是一致的
* @throws InterruptedException
*/
public static void volatileThreadOrder() throws InterruptedException{
VolatileOrderTask task1 = new VolatileOrderTask(holder , 0);
VolatileOrderTask task2 = new VolatileOrderTask(holder , 1);
VolatileOrderTask task3 = new VolatileOrderTask(holder , 2);
Thread thread1 = new Thread(task1);
Thread thread2 = new Thread(task2);
Thread thread3 = new Thread(task3);
thread1.setDaemon(true);
thread2.setDaemon(true);
thread3.setDaemon(true);
thread1.start();
thread2.start();
thread3.start();
Thread.sleep(1 * 1000);
}
}
執行結果
2.3、線程的join方法實現線程順序執行
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 測試線程有序執行
* 使用共享變量的方式:代碼如下
* 利用原子遞增控制線程准入順序
*/
public class ThreadOrder {
public static void main(String[] args) throws InterruptedException {
//atomicIntegerThreadOrder();//使用原子類型實現線程順序執行
//volatileThreadOrder();//使用 volatile變量實現線程順序執行
joinMethodThreadOrder(); //線程的join方法實現線程順序執行
//threadExecutorSubmitOrder();//使用線程池的submit方法實現線程順序執行
}
/**
* Thread的join方法實現線程順序執行
*/
public static void joinMethodThreadOrder(){
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread1: "+Thread.currentThread().getName());
}
}, "T1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
thread1.join();//確定thread1執行完畢
System.out.println("thread2: "+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T2");
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
try {
thread2.join();//確定thread2執行完畢
System.out.println("thread3: "+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "T3");
thread1.start();
thread2.start();
thread3.start();
}
}
執行結果
2.4、線程池的submit方法實現
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 測試線程有序執行
* 使用共享變量的方式:代碼如下
* 利用原子遞增控制線程准入順序
*/
public class ThreadOrder {
private static AtomicInteger count =new AtomicInteger(0);
private static Holder holder = new Holder();
public static void main(String[] args) throws InterruptedException {
//atomicIntegerThreadOrder();//使用原子類型實現線程順序執行
//volatileThreadOrder();//使用 volatile變量實現線程順序執行
//joinMethodThreadOrder(); //線程的join方法實現線程順序執行
threadExecutorSubmitOrder();//使用線程池的submit方法實現線程順序執行
}
/**
* 線程池的submit方法實現線程順序執行
*/
public static void threadExecutorSubmitOrder() {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName("Thread1");
System.out.println("thread1: " + Thread.currentThread().getName());
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName("Thread2");
System.out.println("thread2: " + Thread.currentThread().getName());
}
});
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName("Thread3");
System.out.println("thread3: " + Thread.currentThread().getName());
}
});
//通過線程池實現線程順序執行
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(thread1);
executor.submit(thread2);
executor.submit(thread3);
executor.shutdown();
}
}
執行結果
3、完成源碼地址:
https://github.com/jianxia612/StudySampleJava/tree/master/ThreadOrder