JUC---00创建线程的方式
阅读原文时间:2023年07月10日阅读:1

一、继承Thread类

1 package com.jenne.mydemo;
2
3 public class TestMyThread {
4 public static void main(String[] args) {
5
6 //启动两个线程
7 MyThread my1 = new MyThread();
8 my1.start();
9 MyThread my2 = new MyThread();
10 my2.start();
11 for (int i = 10; i >= 1; i--) {
12 System.out.println(Thread.currentThread().getName() + "线程:======" + i);
13 }
14
15 }
16 }
17
18 //创建线程类
19 class MyThread extends Thread {
20 @Override
21 public void run() {
22 for (int i = 1; i <= 10; i++) {
23 System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");
24 }
25 }
26 }

二、实现Runnable接口

1 package com.jenne.mydemo;
2
3 public class TestMyThread {
4 public static void main(String[] args) {
5
6 //启动两个线程
7 MyThread my1 = new MyThread();
8 my1.start();
9 MyThread my2 = new MyThread();
10 my2.start();
11
12 //主线程运行程序
13 for (int i = 10; i >= 1; i--) {
14 System.out.println(Thread.currentThread().getName() + "线程:======" + i);
15 }
16
17 }
18 }
19
20 //创建线程类
21 class MyThread extends Thread {
22 @Override
23 public void run() {
24 for (int i = 1; i <= 10; i++) {
25 System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");
26 }
27 }
28 }

三、实现Callable接口

package com.jenne.mydemo;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
* Callable接口使用过程:
* 1.创建资源类实现Callable接口,可以设置不同的泛型
* 2.注意Callable不能直接使用,要用第三方类(java.util.concurrent.FutureTask是Runnable接口的实现类)间接实现跟Thread的链接
* 3.创建中间类:FutureTask ft = new FutureTask(new MyCallable());
* 执行使用new Thread(ft).start();
*/

public class TestMyCallable {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask ft = new FutureTask(new MyCallable());
FutureTask ft1 = new FutureTask(new MyCallable());

    //开启两个线程  
    new Thread(ft).start();  
    new Thread(ft1).start();

    //主线程  
    for (int i = 1; i <= 10; i++) {  
        System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");  
    }

    //获取call()方法的返回值  
    System.out.println(ft.get());  
    System.out.println(ft1.get());  
}  

}

class MyCallable implements Callable {

@Override  
public Object call() throws Exception {  
    for (int i = 1; i <= 10; i++) {  
        System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");  
    }  
    return "我是返回值";  
}  

}

四、线程池创建线程

package com.jenne.mydemo;

import org.junit.jupiter.api.Test;

import java.util.concurrent.*;

/**
* 使用Executors工厂类里面的静态方法创建不同的线程池
*   1.创建一个线程池,池里有nThreads个固定的线程
*   public static ExecutorService newFixedThreadPool(int nThreads)
*
*   2.一个任务一个任务的执行,池中只有一个线程
*   public static ExecutorService newSingleThreadExecutor()
*
*   3.池中没有线程,线程池根据需要创建新线程,可扩容,遇强则强
*   public static ExecutorService newCachedThreadPool()
*
* 上述三种使用很少,一般使用自定义线程池java.util.concurrent.ThreadPoolExecutor类:
*  public ThreadPoolExecutor(
*   int corePoolSize, 线程池中的常驻核心线程数
*   int maximumPoolSize, 线程池中能够容纳同时执行的最大线程数,此值必须大于等于1
*   long keepAliveTime, 多余的空闲线程的存活时间当前池中线程数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余线程会被销毁直到只剩下corePoolSize个线程为止
*   TimeUnit unit, keepAliveTime的单位.例:[TimeUnit.SECONDS.sleep(3)]等待3秒
*   BlockingQueue workQueue, 任务队列,被提交但尚未被执行的任务。(后面讲这个阻塞队列)
*   ThreadFactory threadFactory, 表示生成线程池中工作线程的线程工厂,用于创建线程,一般默认的即可
*   RejectedExecutionHandler handler 拒绝策略,表示当队列满了,并且工作线程大于等于线程池的最大线程数(maximumPoolSize)时如何来拒绝请求执行的runnable的策略)
*
* 拒绝策略(实现了 java.util.concurrent.RejectedExecutionHandle接口【当需要执行的线程数量大于maximumPoolSize+workQueue的数量会执行拒绝策略】):
*   AbortPolicy(默认):直接抛出RejectedExecutionException异常阻止系统正常运行
*   CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。
*   DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加人队列中尝试再次提交当前任务。
*   DiscardPolicy:该策略默默地丢弃无法处理的任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一种策略。
*/
public class TestMyExecutorService {

@Test  
public void testFixedThreadPool() {  
    ExecutorService es = Executors.newFixedThreadPool(3);

    //调用submit(new Runnable() )方法开启线程,  
    for (int i = 1; i <= 10; i++) {  
        es.submit(new Runnable() {  
            @Override  
            public void run() {  
                for (int i = 1; i <= 10; i++) {  
                    System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");  
                }  
            }  
        });  
    }

    //main线程执行代码  
    for (int i = 1; i <= 10; i++) {  
        System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");  
    }

    //关闭线程池,使用后线程池被摧毁  
    es.shutdown();  
}

@Test  
public void testSingleThreadExecutor() {  
    ExecutorService es = Executors.newSingleThreadExecutor();

    //调用submit(new Runnable() )方法开启线程,  
    for (int i = 1; i <= 10; i++) {  
        es.submit(new Runnable() {  
            @Override  
            public void run() {  
                for (int i = 1; i <= 10; i++) {  
                    System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");  
                }  
            }  
        });  
    }

    //main线程执行代码  
    for (int i = 1; i <= 10; i++) {  
        System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");  
    }

    //关闭线程池,使用后线程池被摧毁  
    es.shutdown();  
}

@Test  
public void testCachedThreadPool() {  
    ExecutorService es = Executors.newCachedThreadPool();

    //调用submit(new Runnable() )方法开启线程,  
    for (int i = 1; i <= 10; i++) {  
        es.submit(new Runnable() {  
            @Override  
            public void run() {  
                for (int i = 1; i <= 10; i++) {  
                    System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");  
                }  
            }  
        });  
    }

    //main线程执行代码  
    for (int i = 1; i <= 10; i++) {  
        System.out.println(Thread.currentThread().getName() + "线程:======" + i + "次");  
    }

    //关闭线程池,使用后线程池被摧毁  
    es.shutdown();  
}

@Test  
public void testThreadPoolExecutor() {

    ExecutorService es = new ThreadPoolExecutor(  
            2,  
            5,  
            3L,  
            TimeUnit.SECONDS,  
            new ArrayBlockingQueue<Runnable>(3),  
            Executors.defaultThreadFactory(),  
            //new ThreadPoolExecutor.DiscardPolicy()  
            //new ThreadPoolExecutor.DiscardOldestPolicy()  
            new ThreadPoolExecutor.CallerRunsPolicy()  
            //new ThreadPoolExecutor.AbortPolicy()  
    );

    try {  
        for (int i = 1; i <= 10; i++) {  
            es.submit(new Runnable() {  
                @Override  
                public void run() {  
                    System.out.println(Thread.currentThread().getName() + "线程:======");  
                }  
            });  
        }  
    } catch (Exception e) {  
        e.printStackTrace();  
    } finally {  
        //关闭线程池,使用后线程池被摧毁  
        es.shutdown();  
    }  
}  

}