溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java 多線程有序執(zhí)行的幾種方法總結(jié)

發(fā)布時(shí)間:2020-08-31 10:24:13 來(lái)源:腳本之家 閱讀:189 作者:lqh 欄目:編程語(yǔ)言

Java 多線程有序執(zhí)行的幾種方法總結(jié)

同事無(wú)意間提出了這個(gè)問(wèn)題,親自實(shí)踐了兩種方法。當(dāng)然肯定還會(huì)有更多更好的方法。

方法一

import java.util.concurrent.atomic.AtomicInteger;

public class OrderedThread1 {
 
 static AtomicInteger count = new AtomicInteger(0);

 public static void main(String[] args) throws InterruptedException {
 Task task1 = new Task(count, 0);
 Task task2 = new Task(count, 1);
 Task task3 = new Task(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);
 }

}

class Task implements Runnable {
 
 private AtomicInteger count;
 private int order;
 
 public Task(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);
  count.incrementAndGet();
  }
 }
 }
}

    這種方法應(yīng)該是比較常見(jiàn)的解決方案。利用原子遞增控制線程準(zhǔn)入順序。

方法二

public class OrderedThread2 {
 static Holder holder = new Holder();
 public static void main(String[] args) throws InterruptedException {
 
 Task1 task1 = new Task1(holder, 0);
 Task1 task2 = new Task1(holder, 1);
 Task1 task3 = new Task1(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);
 

 }

}

class Task1 implements Runnable {
 
 Holder holder;
 int order;
 
 public Task1(Holder holder, int order) {
 this.holder = holder;
 this.order = order;
 }

 @Override
 public void run() {
 while (true) {
  if (holder.count % 3 == order) {
  System.out.println(Thread.currentThread().getName() + " ===== "+ order);
  holder.count ++;
  }
 }
// int i = 0;
// while(i ++ < 10000){
//  holder.count ++;
// }
 }
}
class Holder {
 volatile int count = 0;
}

    方法二使用了volatile關(guān)鍵字。讓每個(gè)線程都能拿到最新的count的值,當(dāng)其中一個(gè)線程執(zhí)行++操作后,其他兩個(gè)線程就會(huì)拿到最新的值,并檢查是否符合準(zhǔn)入條件。

ps:volatile不是線程安全的。而且兩者沒(méi)有任何關(guān)系。volatile變量不在用戶線程保存副本,因此對(duì)所有線程都能提供最新的值。但試想,如果多個(gè)線程同時(shí)并發(fā)更新這個(gè)變量,其結(jié)果也是顯而易見(jiàn)的,最后一次的更新會(huì)覆蓋前面所有更新,導(dǎo)致線程不安全。在方法二中,一次只有一個(gè)線程滿足準(zhǔn)入條件,因此不存在對(duì)變量的并發(fā)更新。volatile的值是最新的與線程安全完全是不相干的,所以不要誤用volatile實(shí)現(xiàn)并發(fā)控制。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI