深入浅出之java线程池

  • 创建线程的方式

    1.继承Thread类
    class XxxThread extends Thread{
        public void run(){

        }
    }
    new XxxThread().start();

  •     2.实现Runnable接口

     class XxxRunnable implements Runnable{
        public void run(){

        }
    }
    new Thread(new XxxRunnable()).start();

  •     3.匿名内部类

    new Thread(){
        public void run(){
    
        }
    }.start();
    或
    new Thread(new Runnable(){
        public void run(){

        }
    }).start();

  • 4.实现线程安全的方式

    1.同步代码块
        synchronized(锁对象){  }
    2.同步方法
        修饰符 synchronized 返回值类型 方法名(参数列表){}
    3.Lock接口
        void lock() 获取锁
        void unlock() 释放锁
            获取锁和释放锁必须成对出现。

 1.1 线程池概念: 

  • 什么是线程池:一个用来创建和管理线程对象的容器。
  • 线程池的核心思想:线程复用。
  • 线程池的好处:
  1. 减少资源的消耗,避免频繁的创建和销毁线程。
  2. 提高程序的响应速度。
  3. 提高线程的可管理性。

1.2 线程池的使用

1.2.1线程池的创建方式

 如何获得线程池对象:

扫描二维码关注公众号,回复: 2756785 查看本文章
  • 在JDK1.5之后,官方专门提供了一个线程池工具类用来创建线程池对象。
  • 该类叫:Executors,通过该类的静态方法来创建线程池对象,静态方法如下:

       public static ExecutorService newFixedThreadPool(int nThreads); 

       根据指定的线程数量创建线程池对象。

  • ExecutorService接口概述:只要是实现了该接口的对象就是一个线程池对象。
  • ExecutorService接口常用方法:
  1. Future<?> submit(Runnable task);提交Runnable任务
  2. Future<?> submit(Callable<T> task);提交Callable任务(用future接收)
  3. void  shutdown();销毁线程池,会等待线程池中已经提交的所有任务执行完毕之后再销毁。
  4. shutdownNow();立即销毁线程池:如果线程池中还没有开始执行的任务就不会执行了。
  • Future接口概述:
  1. 用来封装Callable任务执行完毕的结果。
  • Future接口常用方法
  1. V get();获得call方法执行完毕的返回值。
  • 线程池提交Runnable任务步骤:
  1. 创建线程池对象并指定线程数量:ExecutorService  tp=Executors.newFixedThreadpool(3)
  2. 创建实现Runnable接口,重写run方法:将线程任务相关的代码写在该方法中
  3. 创建实现类对象,调用线程池对象的submit方法传递实现类对象:tp.submit(new RunnableTask());
  4. 调用线程池对象的shutdown方法销毁线程池:tp.shutdown();
public class RunnableTask implements Runnable {
    @Override
    public void run() {
        System.out.println("这里是线程任务..."+Thread.currentThread().getName());
    }
}



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

public class ThreadPoolDemo01 {
    public static void main(String[] args) {
        //创建线程池对象
        ExecutorService tp=Executors.newFixedThreadPool(3);
        //提交Runnable任务
        tp.submit(new RunnableTask());
        tp.submit(new RunnableTask());
        tp.submit(new RunnableTask());
        tp.submit(new RunnableTask());
        //销毁线程池,在实际开发中一般是不销毁的
        tp.shutdown();
    }
}

 

 1.2.2 提交任务-Callable任务

  • 线程池提交Callable任务步骤:
  1. 创建线程池对象并指定线程数量:ExecutorService  tp=Executors.newFixedThreadpool(3)
  2. 创建类实现Callable接口,重写call方法(有返回值):将线程任务相关的代码写在该方法中
  3. 创建实现类对象,调用线程池对象的submit方法传递实现类对象:tp.submit(new CallableTask());
  4. 调用线程池对象的shutdown方法销毁线程池:tp.shutdown();
import java.util.concurrent.Callable;

public class CallableTask implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("线程任务..."+Thread.currentThread().getName());
        for (int i = 0; i < 10; i++) {
            System.out.println("call+"+i);
        }
        return "abc";
    }
}



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

public class ThreadPoolDemo02 {
    public static void main(String[] args) throws Exception {
        //创建线程池对象
        ExecutorService tp=Executors.newFixedThreadPool(3);

        //提交Callable任务
        Future<String> f= tp.submit(new CallableTask());
        //获得call方法执行完毕的返回值
        //get方法时阻塞的方式,会阻塞当前线程的执行,所以main方法线程的输出在后面
        System.out.println(f.get());
        for (int i = 0; i < 10; i++) {
            System.out.println("main="+i);
        }

        //销毁线程池,在实际开发过程中一般是不销毁的
        tp.shutdown();
    }
}
  • Callable和Runnable接口的选择
  1. 如果任务执行完毕之后需要返回一个结果给调用者,则选择Callable。
  2. 如果任务执行完毕之后不需要返回结果给调用者,则随便选择。
  • 需求说明:调用线程池对象方法提交线程任务,同时执行下面任务:
  • 计算1-100的和
  • 计算1-200的和
import java.util.concurrent.Callable;

public class countTask implements Callable<Integer> {
   private int num;

    public countTask(int num) {
        this.num = num;
    }

    @Override
    public Integer call() throws Exception {
        int sum=0;
        for (int i = 1; i <= num; i++) {
            sum += i;
        }
        return sum;
    }
}




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

public class ThreadPoolDemo03 {
    public static void main(String[] args) throws Exception {
       //创建线程池对象
        ExecutorService tp = Executors.newFixedThreadPool(2);

        //提交Callable任务
        Future<Integer> f1 = tp.submit(new countTask(100));
        Future<Integer> f2 = tp.submit(new countTask(200));
        System.out.println(f1.get());//5050
        System.out.println(f2.get());//20100

        //销毁线程池
        tp.shutdown();
    }
}

猜你喜欢

转载自blog.csdn.net/Huangyuhua068/article/details/81463980