Java 다중 스레드를 순차적으로 실행하는 몇 가지 방법 요약

Java 다중 스레드를 순차적으로 실행하는 몇 가지 방법 요약
동료는 무심결에 이 문제를 제기하고 두 가지 방법을 직접 실천했다.물론 더 좋은 방법이 있을 거야.
방법 1

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();
  }
 }
 }
}

이런 방법은 비교적 흔히 볼 수 있는 해결 방안이어야 한다.원자 점증 제어 라인의 접근 순서를 이용하다.
방법 2

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;
}

방법2는volatile 키워드를 사용했습니다.모든 스레드가 최신count의 값을 받을 수 있도록 하고, 그 중 한 스레드가++ 조작을 실행하면 다른 두 스레드가 최신의 값을 받을 수 있으며, 접근 조건에 부합되는지 검사합니다.
ps:volatile는 라인이 안전하지 않습니다.그리고 둘은 아무런 관계가 없다.volatile 변수는 사용자 라인에 복사본을 저장하지 않기 때문에 모든 라인에 최신 값을 제공할 수 있습니다.그러나 만약 여러 개의 라인이 동시에 이 변수를 업데이트한다면 그 결과도 명백히 알 수 있다. 마지막 업데이트는 앞의 모든 업데이트를 덮어쓰고 라인이 안전하지 않을 것이다.방법 2에서 한 번에 하나의 라인만 접근 조건을 만족시키기 때문에 변수에 대한 병렬 업데이트는 존재하지 않는다.volatile의 값은 최신의 라인 안전과 전혀 상관이 없기 때문에volatile를 오용하여 병발 제어를 실현하지 마십시오.
읽어주셔서 감사합니다. 여러분에게 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!

좋은 웹페이지 즐겨찾기