Java 스레드 풀 일반 방법

5484 단어
java를 통해.util.concurrent.ExecutorService 인터페이스 대상은 도구 클래스java를 통해 작업을 수행합니다.util.concurrent.Executors의 정적 방법으로 생성됩니다.
Executors 이 패키지에 정의된 Executor, Executor 서비스, ScheduledExecutor 서비스, ThreadFactory,Callable 클래스의 공장과 실용적인 방법입니다.
Executor Service는 관리 종료 방법과 비동기 작업의 실행 상황을 추적하기 위해 Future를 생성할 수 있는 방법을 제공합니다.Executor Service를 닫으면 새 작업 수락이 중단됩니다.종료하면 실행 프로그램이 마지막으로 종료됩니다. 실행 중인 작업도, 실행을 기다리는 작업도, 새 작업을 제출할 수 없습니다.
  executorService.execute(new TestRunnable());
1. ExecutorService 만들기
도구클래스java를 통해util.concurrent.Executors의 정적 방법으로 생성됩니다.
Executors 이 패키지에 정의된 Executor, Executor 서비스, ScheduledExecutor 서비스, ThreadFactory,Callable 클래스의 공장과 실용적인 방법입니다.
예를 들어, Executor Service의 인스턴스를 만들면 Executor Service는 실제로 스레드 풀의 관리 도구입니다.
  ExecutorService executorService = Executors.newCachedThreadPool();
  ExecutorService executorService = Executors.newFixedThreadPool(3);
  ExecutorService executorService = Executors.newSingleThreadExecutor();
2. 임무를 라인에 추가하여 수행한다
하나의 작업을 스레드 탱크에 추가할 때, 스레드 탱크는 모든 작업에 스레드를 만들고, 이 스레드는 다음 시간에 자동으로 실행됩니다.
3. 실행 서비스 대상을 닫는다
  executorService.shutdown();
package javaBasic;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *  Callable 
 * 
 * @author markGao
 * 
 */
public class ExecutorServiceSample {

    public static void main(String[] args) {
        int numberOfThreads = java.lang.Runtime.getRuntime()
                .availableProcessors();

        ExecutorService pool = Executors.newFixedThreadPool(numberOfThreads);

        for (int i = 0; i < numberOfThreads; i++) {
            pool.execute(new TestRunnable());
            System.out.println("************* execute Processors" + i
                    + " *************");
        }
        pool.shutdown();

    }

}

/**
 * Runnable 
 * 
 * @author markGao
 * 
 */
class TestRunnable implements Runnable {
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 。");
        while (true) {
            try {
                Thread.sleep(5000);
                System.out.println(Thread.currentThread().getName());
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

5. 작업 수행의 반환값 얻기
자바5 이후 임무는 두 가지로 나뉜다. 하나는 Runnable 인터페이스를 실현한 클래스이고, 하나는 Callable 인터페이스를 실현한 클래스이다.둘 다 Executor Service에서 실행할 수 있지만, Runnable 작업은 값을 되돌려주지 않고,Callable 작업은 값을 되돌려줍니다.또한Callable의call() 방법은ExecutorService의submit(Callabletask) 방법으로만 실행할 수 있으며 Future를 되돌려줍니다. 이것은 작업이 완성되기를 기다리는Future를 의미합니다.
public interface Callable 결과가 반환되고 예외적인 작업이 발생할 수 있습니다.실현자는 매개 변수가 없는 콜이라고 하는 방법을 정의했다.
Callable 인터페이스는 Runnable와 유사하며, 둘 다 다른 라인에서 실행될 수 있는 클래스를 위한 것입니다.그러나 Runnable은 결과를 되돌려주지 않고 검사를 거친 이상을 던질 수 없습니다.
Executors 클래스에는 다른 일반적인 형식에서Callable 클래스로 전환하는 실용적인 방법이 포함되어 있습니다.
Callable의 콜 () 방법은 Runnable의run () 방법과 유사합니다. 전자는 되돌아오는 값이 있고 후자는 없습니다.
Callable의 대상을 Executor 서비스의submit 방법에 전달하면, 이 call 방법은 자동으로 하나의 라인에서 실행되고, 실행 결과인Future 대상을 되돌려줍니다.
마찬가지로 Runnable의 대상을 Executor 서비스의submit 방법에 전달하면 이run 방법은 자동으로 한 라인에서 실행되고 실행 결과인Future 대상을 되돌려줍니다. 그러나Future 대상에서 get 방법을 호출하면null로 되돌려줍니다.
package javaBasic;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class CallableDemo {
    public static void main(String[] args) {
        // get available Processors
        int numberOfThreads = java.lang.Runtime.getRuntime()
                .availableProcessors();
        ExecutorService executorService = Executors
                .newFixedThreadPool(numberOfThreads);
        List<Future<String>> resultList = new ArrayList<Future<String>>();

        // create ten tasks
        for (int i = 0; i < 10; i++) {
            // use ExecutorService to execute taks of Callable Type, and save
            // result into future.
            Future<String> future = executorService
                    .submit(new TaskWithResult(i));
            // task result save into List
            resultList.add(future);
        }

        // Traversal Task
        for (Future<String> fs : resultList) {
            try {
                // print every thread result
                System.out.println(fs.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                executorService.shutdown();
            }
        }
    }
}

class TaskWithResult implements Callable<String> {
    private int id;

    public TaskWithResult(int id) {
        this.id = id;
    }

    public String call() throws Exception {
        System.out.println(System.currentTimeMillis()
                + " Start call() invoked " + id + " "
                + Thread.currentThread().getName());
        // for (int i = 9999999; i > 0; i--)
        // ;
        Thread.sleep(5000);
        return System.currentTimeMillis() + " End call() invoked " + id
                + "    " + Thread.currentThread().getName();
    }
}

스레드 탱크는 두 가지 다른 문제를 해결할 수 있다. 모든 임무의 호출 비용을 줄이기 때문에, 그들은 대량의 비동기 임무를 수행할 때 강화된 성능을 제공할 수 있고, 자원을 귀속하고 관리할 수 있으며 (집합 임무를 수행할 때 사용하는 스레드 포함) 하는 방법도 제공할 수 있다.모든 ThreadPoolExecutor는 완성된 작업 수와 같은 기본적인 통계 데이터를 유지하고 있다.

좋은 웹페이지 즐겨찾기