欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线程池

程序员文章站 2022-05-06 08:00:55
...
  1. 线程池的思想
  2. Runnable方式使用线程池
  3. Callable方式使用线程池
  4. 死锁

什么是线程池:

存放线程的容器

创建一个线程执行一个任务的缺点:

  • 我们创建一个线程执行任务后线程死亡.如果线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
  • 比如:中午吃完饭将碗洗干净,晚上接着使用 重复利用,可以节省资源 线程池的好处:

线程池

2.Runnable方式使用线程池

创建线程池、Executors类:

  • static ExecutorService newFixedThreadPool​(int nThreads) 新建固定线程数量的线程池
  • int nThreads: 指定线程池中线程的数量
  • ExecutorService: 线程池(接口)

Runnable方式使用线程池步骤:

1.创建任务
2.创建线程池
3.往线程池提交任务

// 1.创建任务
public class MyRunnable implements Runnable {
    @Override
    public void run() { // 新的线程会来执行任务
        System.out.println(Thread.currentThread().getName() + "执行啦");
    }
}

测试类:
public static void main(String[] args) {
        // 2.创建线程池
        ExecutorService pool = Executors.newFixedThreadPool(3);
        // System.out.println("pool = " + pool);
        MyRunnable mr = new MyRunnable();

        // 3.往线程池提交任务
        pool.submit(mr);
        pool.submit(mr);
        pool.submit(mr);
        pool.submit(mr);
        pool.submit(mr);

        // 关闭线程池(工作中不需要关闭线程池,7x24)
        pool.shutdown();
    }

3.Callable方式使用线程池

Callable方式好处:

1.可以抛异常
2.可以有返回值

Callable方式使用线程池步骤?

1.创建一个Callable任务
2.创建线程池
3.提交任务

如何拿到Callable的返回值?

通过Future的get方法

// 1.创建一个Callable任务
public class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName() + "执行啦");
        return 110;
    }
}

测试类:
 public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 2.创建线程池
        ExecutorService pool = Executors.newFixedThreadPool(3);
        MyCallable mc = new MyCallable();

        // 3.提交任务
        pool.submit(mc);
        pool.submit(mc);
        pool.submit(mc);
        pool.submit(mc);
        Future<Integer> future = pool.submit(mc);
        // 因为不是直接调用call方法,不能直接拿到返回
        // 当我们条任务后,线程会来执行call方法,会得到返回值,会将返回值放到Future对象中
        // 我们通过Future的get方法得到返回值
        System.out.println(future.get());

        pool.shutdown();
    }

4.死锁

什么是死锁:

多线程竞争共享资源,导致多个线程相互等待,程序无法向下执行

死锁产生的条件:

1.有多个线程
2.有多把锁
3.有同步代码块嵌套

如何避免死锁:

干掉其中某个条件

public class Demo05 {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
new Thread(mr).start();
new Thread(mr).start();
	}
}


class MyRunnable implements Runnable {
    Object objA = new Object();
    Object objB = new Object();

    /*
    嵌套1 objA
    嵌套1 objB
    嵌套2 objB
    嵌套1 objA
    */
    @Override
    public void run() {
        synchronized (objA) {
            System.out.println("嵌套1 objA");
            synchronized (objB) {// t2, objA, 拿不到B锁,等待
                System.out.println("嵌套1 objB");
            }
        }
        synchronized (objB) {
            System.out.println("嵌套2 objB");
            synchronized (objA) {// t1 , objB, 拿不到A锁,等待
                System.out.println("嵌套2 objA");
            }
        }
    }
}