Thinking in 자바-Concurrent 패키지 의 새로운 구성 요소 학습+경마 게임 시 뮬 레이 션
1.countDownlatch 가 Countdownlatch 대상 을 사용 할 때 초기 계수 값 을 설정 한 다음 이 대상 에서 await()를 호출 하 는 작업 은 이 대상 의 계수 값 이 0 으로 줄 어 들 때 까지 막 힙 니 다.다른 임 무 는 자신의 일 을 완성 할 때 이 대상 의 countDown()방법 을 사용 하여 이 대상 의 계산 치 를 줄 일 수 있 습 니 다.따라서 이 종 류 는 하나 이상 의 작업 을 동기 화하 고 다른 작업 이 실 행 될 때 까지 기다 리 도록 강제 할 수 있 습 니 다.하나의 전형 적 인 응용 장면 은 하나의 프로그램 을 n 개의 서로 독립 된 해결 가능 한 작업 으로 분해 하고 n 의 Countdown Latch 를 만 드 는 것 입 니 다.모든 작업 이 완 료 될 때 이 대상 에서 countDown()을 호출 합 니 다.이 문제 가 해결 되 기 를 기다 리 는 작업 은 이 대상 에서 await()를 호출 하여 이 대상 의 계수 값 이 0 으로 줄 어 들 때 까지 차단 합 니 다.또 주의해 야 할 것 은 이 대상 이 n 개 임무 수행 의 우선 순 위 를 조율 하지 않 는 다 는 점 이다.다음은 이 기술 의 프레임 워 크 예 시 를 보 여 줍 니 다.
package lkl;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* CountDownLatch ,
*
* */
//
class TaskPortion implements Runnable{
private static int counter = 0;
private final int id= counter++;
// Random ,
// Random.next() ,
private static Random rand = new Random(47);
private final CountDownLatch latch;
public TaskPortion(CountDownLatch latch){
this.latch = latch;
}
public void run(){
try{
dowork();
latch.countDown(); //
}catch(InterruptedException ex){
System.out.println(this+" ");
}
}
//
public void dowork() throws InterruptedException{
TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
System.out.println(this+" completed");
}
public String toString(){
return String.format("%1$-3d", id);
}
}
class WaitingTask implements Runnable{
private static int counter = 0;
private final CountDownLatch latch;
private final int id = counter++;
public WaitingTask(CountDownLatch latch){
this.latch = latch;
}
public void run() {
try{
latch.await();; // latch 0 ,
System.out.println(this+" completed");
}catch(InterruptedException ex){
System.out.println();
}
}
public String toString(){
return String.format("WatitingTask %1$-3d", id);
}
}
public class CountDownLatchDemo {
static final int SIZE = 100;
public static void main(String[] args) throws Exception{
ExecutorService exec = Executors.newCachedThreadPool();
// latch
// 100, 100
// await()
CountDownLatch latch = new CountDownLatch(SIZE);
// 10
for(int i=0; i<10; i++){
exec.execute(new WaitingTask(latch));
}
// 100
for(int i=0; inew TaskPortion(latch));
}
System.out.println("Latched all takss");
exec.shutdown();
}
}
2.cyclicbarrier Cyclicbarrier 는 이러한 상황 에 적 용 됩 니 다.우 리 는 하나의 작업 을 만 들 고 다음 단 계 를 진행 하기 전에 모든 작업 이 완 료 될 때 까지 기다 리 고 싶 습 니 다.(정상 적 인 스 레 드 에 따라 스케줄 링 을 하 는 것 은 불가능 합 니 다)그것 은 모든 임 무 를 울타리 에 줄 을 서 게 하기 때문에 일치 하 게 앞으로 이동 할 수 있다.이것 은 위의 Countdown Latch 와 유사 해 보이 지만 Countdown Latch 는 한 번 만 이벤트 가 발생 할 수 있 습 니 다.CyclicBarrier 는 여러 번 다시 사용 할 수 있 습 니 다.더 구체 적 인 사용 은 다음 과 같 습 니 다.우 리 는 초기 계수 값 을 n 과 Runnable 대상 을 r 로 지정 한 CyclicBarrier 이미 지 를 만 든 다음 n 개의 스 레 드 에 제출 합 니 다.모든 스 레 드 는 현재 작업 을 완료 한 후에 이 대상 의 await()를 호출 하여 계수 값 을 줄 이 고 현재 스 레 드 가 막 힙 니 다.이렇게 하면 마지막 스 레 드 가 await()를 호출 하여 계수 값 을 0 으로 줄 인 다음 에 이 Cyclibarrier 대상 의 r run()방법 을 호출 합 니 다.run()방법 이 실 행 된 후에 Cyclic Barrier 대상 의 계수 값 을 리 셋 한 다음 에 위의 과정 을 반복 합 니 다.이러한 과정 을 통 해 여러 스 레 드 를 일치 하 게 앞으로 이동 시 키 는 효과 가 있다.다음은 이 종 류 를 사용 하여 경마 게임 을 모방 합 니 다.
package lkl;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
*
* "*" , "=="
* : ,
* ; CyclicBarrier
* , 。 CycylicBarrier run()
* 。
* , 。
* */
//
class Horse implements Runnable{
private static int counter = 1;
private final int id = counter++;//
private int strides = 0; //
private static Random rand = new Random(47);
private static CyclicBarrier barrier;// CyclicBarrier
public Horse(CyclicBarrier b){
barrier = b;
}
//
public synchronized int getStrides(){
return strides;
}
public void run(){
try
{
while(!Thread.interrupted()){
synchronized(this){
//
strides+=rand.nextInt(3); //0,1,2
}
//
// barrier run() , ,
// ,
// , 。
// , 。
barrier.await();
}
}
catch(InterruptedException ex){
System.out.println(this+ " ");
}catch(BrokenBarrierException e){//await()
throw new RuntimeException();
}
}
public String toString(){
return "Horse "+id+" ";
}
// "*"
public String tracks(){
StringBuilder s = new StringBuilder();
for(int i=0 ;i"*");
}
s.append(id);
return s.toString();
}
}
public class HorseRace {
static final int FINISH_LINE=75; //
private List horses = new ArrayList();
private ExecutorService exec = Executors.newCachedThreadPool();
private CyclicBarrier barrier;
public HorseRace(int nHorse,final int pause){
// CyclicBarrier Runnable 0
// , 。 Runnable
// 。
barrier = new CyclicBarrier(nHorse,new Runnable(){
public void run(){
StringBuilder s = new StringBuilder();
//
for(int i=0 ; i"=");
}
System.out.println(s);
// (“*”+id )
for(Horse horse : horses){
System.out.println(horse.tracks());
}
// ,
// ( )
for(Horse horse: horses){
if(horse.getStrides()>=FINISH_LINE){
System.out.println(horse+" won");
exec.shutdownNow();
return;
}
}
try{
//
TimeUnit.MILLISECONDS.sleep(pause);
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
});
// nHorse
for(int i=0; inew Horse(barrier);
horses.add(horse);
exec.execute(horse);
}
}
public static void main(String[] args){
// 7
int nHorses = 7;
int pause = 200;
new HorseRace(nHorses,pause);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java 에서 Unsupported Operation 예외 이해자바 Collection 인터페이스 에서 각종 추가 또는 제거 방법 을 실행 하 는 것 은 선택 할 수 있 는 작업 입 니 다. 즉, 클래스 를 실현 하 는 것 은 이러한 방법 에 기능 정 의 를 제공 할 필요 가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.