스레드의 Sike 자바 시리즈는 스레드 여덟 가지 방법을 만들 수 있습니다

(수평 스크린 휴대 전화가 볼 수있는 소스 코드가 더 편리합니다)

문제

(1) 스레드를 만들 수있는 다른 방법은 무엇입니까?

(2) 그들은 어떤 장면을 사용하고 있습니까?

간략한 소개

통 형제, 당신은 무엇을 알고, 스레드를 생성하는 방법에 대한 팔가지 요약, 멀티 스레드 프로그래밍의 가장 기본적인 작업입니다, 스레드를 만드시겠습니까?

Thread 클래스를 상속 및 실행 () 메소드를 오버라이드 (override)

public class CreatingThread01 extends Thread {

    @Override
    public void run() {
        System.out.println(getName() + " is running");
    }

    public static void main(String[] args) {
        new CreatingThread01().start();
        new CreatingThread01().start();
        new CreatingThread01().start();
        new CreatingThread01().start();
    }
}复制代码

Thread 클래스를 상속 및 실행 () 메소드를 오버라이드 (override),이 방법의 단점은 클래스는 클래스 자체가 다른 클래스를 상속의 경우는이 식으로 사용할 수 없습니다, 부모 클래스에서 상속 할 수 있다는 것입니다.

Runnable를 구현

public class CreatingThread02 implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " is running");
    }

    public static void main(String[] args) {
        new Thread(new CreatingThread02()).start();
        new Thread(new CreatingThread02()).start();
        new Thread(new CreatingThread02()).start();
        new Thread(new CreatingThread02()).start();
    }
}复制代码

이 방법의 장점을 달성하기 위해 실행 가능한 인터페이스는 클래스가 여러 인터페이스를 구현할 수 있다는 것입니다, 그것은 그것의 후임 시스템에 영향을주지 않습니다.

익명 내부 클래스

public class CreatingThread03 {
    public static void main(String[] args) {
        // Thread匿名类,重写Thread的run()方法
        new Thread() {
            @Override
            public void run() {
                System.out.println(getName() + " is running");
            }
        }.start();

        // Runnable匿名类,实现其run()方法
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " is running");
            }
        }).start();
        
        // 同上,使用lambda表达式函数式编程
        new Thread(()->{
            System.out.println(Thread.currentThread().getName() + " is running");
        }).start();
    }
}复制代码

지금 일반적으로 세 번째 (java8의 +)를 사용하는, 세 번째는 람다를 사용하는 것입니다, 두 번째는 들어오는 익명의 Runnable 클래스, 간단하고 빠른 익명 클래스, 스레드의 run () 메소드를 재 작성 중 하나를 사용합니다.

Callabe 인터페이스를 달성

public class CreatingThread04 implements Callable<Long> {
    @Override
    public Long call() throws Exception {
        Thread.sleep(2000);
        System.out.println(Thread.currentThread().getId() + " is running");
        return Thread.currentThread().getId();
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Long> task = new FutureTask<>(new CreatingThread04());
        new Thread(task).start();
        System.out.println("等待完成任务");
        Long result = task.get();
        System.out.println("任务结果:" + result);
    }
}复制代码

Callabe 인터페이스를 달성, 당신은 실행 스레드의 결과를 얻을 수 있습니다, FutureTask 실제로 실행 가능한 인터페이스를 구현합니다.

타이머 (java.util.Timer)

public class CreatingThread05 {
    public static void main(String[] args) {
        Timer timer = new Timer();
        // 每隔1秒执行一次
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " is running");
            }
        }, 0 , 1000);
    }
}复制代码

빠르게 타이밍 작업을 달성 할 수 java.util.Timer를 사용하여 타이머, TimerTask를 실제로 실행 가능한 인터페이스를 구현합니다.

스레드 풀

public class CreatingThread06 {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 100; i++) {
            threadPool.execute(()-> System.out.println(Thread.currentThread().getName() + " is running"));
        }
    }
}复制代码

스레드 풀을 사용하여, 그것은 다중 스레드를 할 수 있습니다, 시스템 리소스를 절약.

병렬 컴퓨팅 (Java8 +)

public class CreatingThread07 {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        // 串行,打印结果为12345
        list.stream().forEach(System.out::print);
        System.out.println();
        // 并行,打印结果随机,比如35214
        list.parallelStream().forEach(System.out::print);
    }
}复制代码

병렬 컴퓨팅 접근 방식의 사용은 멀티 스레드 병렬 실행을 실행중인 프로그램의 효율성을 향상시킬 수 있습니다.

봄 비동기 방법

첫째,과 수업 시작 springboot @EnableAsync주석 (@EnableAsync 스프링 여기에 예를 쉽게 사용 springboot을 위해 지원됩니다).

@SpringBootApplication
@EnableAsync
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}复制代码

둘째, 방법은 추가 @Async의견.

@Service
public class CreatingThread08Service {

    @Async
    public void call() {
        System.out.println(Thread.currentThread().getName() + " is running");
    }
}复制代码

그런 다음, 직접 일반 서비스를 사용하여 정확히 같은 방법으로 테스트 케이스.

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class CreatingThread08Test {

    @Autowired
    private CreatingThread08Service creatingThread08Service;

    @Test
    public void test() {
        creatingThread08Service.call();
        creatingThread08Service.call();
        creatingThread08Service.call();
        creatingThread08Service.call();
    }
}复制代码

결과는 다음과 같습니다 :

task-3 is running
task-2 is running
task-1 is running
task-4 is running复制代码

당신은 모든 메소드 실행을 사용하는 스레드가 동일하지 않습니다 볼 수 있습니다.

봄 비동기 방법을 사용, 이전과 논리가 같은 SMS 기능을 보내는 등 비동기 호출을 위해 사용되는 방법 중 일부와 연결되지 않은 후 매우 편리라고 할 수 있습니다.

개요

(1) Thread 클래스 상속과 재정의 run () 메소드;

(2)의 Runnable 구현;

(3) 익명 내부 클래스;

(4) Callabe 인터페이스를 구현하고;

(5) 타이머합니다 (java.util.Timer);

(6) 스레드 풀;

(7) 병렬 컴퓨팅 (Java8 +);

(8) 스프링 비동기 방법;

달걀

결국 그들 사이에 존재하므로 위의 상속 Thread 클래스의 두 가지 유형에 본질적으로 사실 스레드를 만들 수있는 많은 방법을 설명하고 run () 메소드를 오버라이드 (override), 하나의 Runnable 인터페이스를 달성하기 위해 () 메소드를 실행 어떤 링크?

스레드를 계승하면서, 다음의 예를 고려하고 Runnable를 구현하고, 어떤 출력을해야합니까?

public class CreatingThread09 {

    public static void main(String[] args) {
        new Thread(()-> {
            System.out.println("Runnable: " + Thread.currentThread().getName());
        }) {
            @Override
            public void run() {
                System.out.println("Thread: " + getName());
            }
        }.start();
    }
}复制代码

여기서 우리는 Thread 클래스의 소스 코드를 볼 필요가 :

public class Thread implements Runnable {
    // Thread维护了一个Runnable的实例
    private Runnable target;
    
    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }
    
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
    
    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        // ...
        // 构造方法传进来的Runnable会赋值给target
        this.target = target;
        // ...
    }
    
    @Override
    public void run() {
        // Thread默认的run()方法,如果target不为空,会执行target的run()方法
        if (target != null) {
            target.run();
        }
    }
}复制代码

여기를 참조하십시오 갑자기 아닌가요? 상기 예 때문에, 실제로는 소스에있어서, 스레드 실행 () 스레드의 실행 방법을 재 기입하는 것과 나사산을 상속 실행 가능한 인터페이스를 구현 () 실제로 타겟 방법에 무관하다.

따라서, 위의 예에서, 출력 Thread: Thread-0, 출력은 스레드 실행 (콘텐츠 법) 재기록.

나는 대중 번호의 관심을 환영보기 소스 코드를 더 시리즈, 바다의 형제 통 소스 "통 형제 소스 읽기는"함께 수영.

QR 코드

추천

출처juejin.im/post/5d9ab5dae51d4578453274ba