자바 는 5 개의 스 레 드 를 사용 하여 배열 의 합 을 계산한다.

9176 단어 Java스 레 드배열
머리말
이전에 다 중 스 레 드 누적 계 수 를 썼 는데 원 리 는 본 편 과 유사 하 다.
누적 계 수 는 계산 배열 의 논리 보다 조금 간단 하 며,이 익숙 하지 않 은 것 에 대해 서 는 먼저 누적 계 수 를 볼 수 있다.
기본 사상 은 이미 이전의 그 문장 에 썼 는데,여기에 바로 코드 를 붙 였 다.
여 기 는 각각 자신 이 스 레 드 를 만들어 기능 을 실현 하고 스 레 드 탱크 를 통 해 기능 을 실현 합 니 다.생각 이 많이 다 르 지 않다.다만 코드 작성 방법 은 조금 다르다.참고 로 제공 하 다.
코드 1:
다섯 개의 스 레 드 교체 누적 계산 배열 의 합,이런 방법 은 사실 한 스 레 드 가 직접 누적 되 는 것 보다 못 하 다.왜냐하면 교체 누적 은 앞의 스 레 드 계산 결과 가 필요 하기 때문이다.

package test;
 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class FiveThreadCount {
 private int count=0;
 private int[] arr={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28};
 private int j=0;
 //      ,     
 private class MyThread extends Thread{
  @Override
  public void run() {
   super.run();
    while(j<arr.length)
    {
     synchronized (MyThread.class) {
      if(j>=arr.length){
       return;
      }
      count+=arr[j++];
      try {
       Thread.sleep(100);
      } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName());
     }
    }
  }
 }
 
 //   
 public void test1(){
  for(int i=0;i<5;i++){
   new MyThread().start();
  }
        try {
   Thread.sleep(10000);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
        System.out.println(count);
 }
 //   
 public void test2(){
  Thread myThread=new MyThread();
  for(int i=0;i<5;i++){
   new Thread(myThread).start();
  }
        try {
   Thread.sleep(10000);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
        System.out.println(count);
 }
 //          
 public void test3(){
  ExecutorService service=Executors.newCachedThreadPool();
  for(int i=0;i<5;i++){
   service.execute(new MyThread());
  }
        try {
   Thread.sleep(10000);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
        System.out.println(count);
 }
 //          
 public void test4(){
  ExecutorService service=Executors.newCachedThreadPool();
  Thread myThread=new MyThread();
  for(int i=0;i<5;i++){
   service.execute(myThread);
  }
        try {
   Thread.sleep(10000);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
        System.out.println(count);
 }
 
}
위의 코드 에서 sleep 방법 을 사용 한 이 유 는 sleep(100)은 다른 스 레 드 가 임 무 를 수행 할 시간 이 있 도록 하기 위해 서 입 니 다.sleep 가 없 으 면 한 스 레 드 가 모두 실 행 될 수 있 습 니 다.마지막 sleep(10000)은 모든 스 레 드 가 실 행 된 후에 마지막 계산 결 과 를 인쇄 하기 위해 서 입 니 다. 
코드 2:
배열 을 5 등분 으로 나 누 어 모든 스 레 드 로 하여 금 자신 이 맡 은 몫 을 계산 하고 동시에 계산 하 게 하 며 마지막 으로 결 과 를 종합 하 게 한다.이런 방식 은 코드 보다 속도 가 좀 빠 를 것 이다.스 레 드 가 독립 적 으로 계산 되 기 때문에 다른 스 레 드 의 결과 에 의존 하지 않 습 니 다.마지막 몇 개의 스 레 드 는 총 수 를 누적 하면 된다.
방식 1:
Callable,Future Task 방식 을 사용 하여 코드 를 실현 합 니 다.

package test;
 
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
 
public class FiveThreadCount2 {
 private int[] arr={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28};
 private int total=0;
 public void test() throws InterruptedException, ExecutionException{
  ExecutorService service=Executors.newFixedThreadPool(5);
  int length=arr.length;
  for(int j=0;j<length;j+=(length/5)){
   FutureTask<Integer> task;
   if( (j+(length/5))<length){
    task=new FutureTask<Integer>(new MyCallable(arr, j, j+(length/5)));
   }else{
    task=new FutureTask<Integer>(new MyCallable(arr, j, length));
   }
   service.execute(task);
   total+=task.get();
  }
  service.shutdown();
  System.out.println(total);
 
 }
 
 public class MyCallable implements Callable<Integer>{
  int[] arr;
  int startIndex;
  int endIndex;
  public MyCallable(int[] arr,int startIndex,int endIndex){
   this.arr=arr;
   this.startIndex=startIndex;
   this.endIndex=endIndex;
  }
  @Override
  public Integer call() throws Exception {
   int sum=0;
   for(int i=startIndex;i<endIndex;i++){
    sum+=arr[i];
   }
   System.out.println(Thread.currentThread().getName());
   return sum;
  }
 }
 
}
이 방식 은 5 개의 스 레 드 가 비동기 적 으로 실행 되 는 것 처럼 보 이 는 단점 이 있 는데 사실은 순서대로 실행 되 기 때문이다. task.get 은 스 레 드 가 실 행 될 때 까지 기 다 려 야 다음 코드 를 실행 할 수 있 습 니 다.그래서 효율 이 높 지 않 고 다른 방법 으로 이 문 제 를 해결 할 수 있 기 때문에 여기 서 깊이 연구 하지 않 는 다.
방식 2:
자바 도구 류 CountDownlatch 를 통 해 동시 계산 을 실현 합 니 다.

package test;
 
import java.util.concurrent.CountDownLatch;
 
public class FiveThreadCount3 {
 private int[] arr={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28};
 private int total=0;
 public void test() throws InterruptedException{
  int length=arr.length;
  CountDownLatch latch=new CountDownLatch(length%5==0?5:6);
  System.out.println(length);
  for(int j=0;j<length;j+=(length/5)){
   MyThread task;
   if( (j+(length/5))<=length){
    task=new MyThread(arr, j, j+(length/5), latch);
   }else{
    task=new MyThread(arr, j, length, latch);
   }
   new Thread(task).start();
  }
  latch.await();
  System.out.println(total);
 }
 
 private class MyThread implements Runnable{
  int[] arr;
  int startIndex;
  int endIndex;
  CountDownLatch latch;
  public MyThread(int[] arr,int startIndex,int endIndex,CountDownLatch latch){
   this.arr=arr;
   this.startIndex=startIndex;
   this.endIndex=endIndex;
   this.latch=latch;
  }
  @Override
  public void run() {
   int sum=0;
   for(int i=startIndex;i<endIndex;i++){
    sum+=arr[i];
   }
   synchronized (MyThread.class) {
    total+=sum;
   }
 
   System.out.println(Thread.currentThread().getName());
   latch.countDown();
 
  }
  
 }
}
Count Downlatch 에 익숙 하지 않 은 것 은 검색 해서 사용 할 수 있 습 니 다. 
방식 3:
자바 도구 클래스 를 통 해 Cyclic Barrier 병행 계산 실현.

package test;
 
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
 
 
public class FiveThreadCount1 {
 private int[] arr={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28};
 private int total=0;
 public void test() throws InterruptedException, BrokenBarrierException{
  int length=arr.length;
  CyclicBarrier barrier=new CyclicBarrier((length%5==0?5:6)+1);
  System.out.println(length);
  for(int j=0;j<length;j+=(length/5)){
   MyThread task;
   if( (j+(length/5))<=length){
    task=new MyThread(arr, j, j+(length/5), barrier);
   }else{
    task=new MyThread(arr, j, length, barrier);
   }
   new Thread(task).start();
  }
  barrier.await();
  System.out.println(total);
 }
 
 private class MyThread implements Runnable{
  int[] arr;
  int startIndex;
  int endIndex;
  CyclicBarrier barrier;
  public MyThread(int[] arr,int startIndex,int endIndex,CyclicBarrier barrier){
   this.arr=arr;
   this.startIndex=startIndex;
   this.endIndex=endIndex;
   this.barrier=barrier;
  }
  @Override
  public void run() {
   int sum=0;
   for(int i=startIndex;i<endIndex;i++){
    sum+=arr[i];
   }
   synchronized (MyThread.class) {
    total+=sum;
   }
   
   try {
    System.out.println(Thread.currentThread().getName());
    barrier.await();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (BrokenBarrierException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  
 }
}
총결산
전체적으로 말 하면 코드 2 의 방식 은 2,3 이 고 효율 이 높 을 것 이다.이상 코드 는 main 방법 을 통 해 예제 코드 를 호출 하 는 test 방법 으로 출력 결 과 를 콘 솔 로 보 냅 니 다. 
자바 가 5 개의 스 레 드 를 사용 하여 배열 의 합 을 계산 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 스 레 드 배열 과 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기