线程池 并发队列

并发队列:两种: 阻塞队列,非阻塞队列

线程池 -- 阻塞队列

非阻塞队列 

public class Test01 {
    public static void main(String[] args) {
        // 无边界队列:没有长度限制
        ConcurrentLinkedQueue<String> clq = new ConcurrentLinkedQueue<>();
        // 入队
        clq.add("java");
        clq.add("MySQL");
        clq.add("Spring");

        // 出队:
        System.out.println(clq.poll()); // java -- 出队,并且在队列中移除元素
        System.out.println(clq.size()); // 2

        System.out.println("----------------");
        System.out.println(clq.peek()); // MySQL -- 输出,但是不在队列中移除元素
        System.out.println(clq.size()); // 2
    }
}

 阻塞队列

public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        /***
         * 查看API得知:
         * BlockingQueue是个接口
         * ArrayBlockingQueue, DelayQueue, LinkedBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue
         */
        LinkedBlockingQueue<String> bq = new LinkedBlockingQueue<>(3);// 长度为3
        bq.offer("Java");
        bq.offer("C++");
        bq.offer("PHP");
        System.out.println(bq.poll());
        bq.offer("Oracle",3, TimeUnit.SECONDS);
        System.out.println(bq.poll());
        System.out.println(bq.poll());
        System.out.println(bq.poll());
    }
}

线程池底层原理--> ThreadPoolExecutor

public class ThreadPool {
    public static void main(String[] args) {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 3, TimeUnit.SECONDS, new LinkedBlockingDeque<>(3));
        // 利用线程池里的线程开始执行任务:
        // 执行第一个任务
        pool.execute(new TestThread());

        // 执行第2个任务
        pool.execute(new TestThread());
        pool.execute(new TestThread());
        pool.execute(new TestThread());

        // 执行第4个任务
        pool.execute(new TestThread());
        // 核心线程执行一个,队列里有三个,这时再创建一个新的线程
        // 线程池有几个线程:2个 : 一个核心线程+ 一个新创建好的线程 == 最大线程数2
        
        // 执行第5个任务
        pool.execute(new TestThread()); // 出现异常

        // 关闭线程池:
        pool.shutdown();
    }
}

class TestThread implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

线程池的分类

可缓存 , 定长 , 定时 , 单例

// 可缓存
public class Test01 {
    public static void main(String[] args) {
        ExecutorService es = Executors.newCachedThreadPool();
        for (int i =1;i<=100;i++){
            es.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }
        es.shutdown();
    }
}
// 定长 --> 核心进程数
public class Test01 {
    public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(3);
        for (int i =1;i<=100;i++){
            es.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }
        es.shutdown();
    }
}
// 定时
public class Test01 {
    public static void main(String[] args) {
        ScheduledExecutorService ses = Executors.newScheduledThreadPool(3);
        for (int i =1;i<=100;i++){
           ses.schedule(new Runnable() {
               @Override
               public void run() {
                   System.out.println(Thread.currentThread().getName());
               }
           },3, TimeUnit.SECONDS);
        }
        ses.shutdown();
    }
}
// 单例
public class Test01 {
    public static void main(String[] args) {
        ExecutorService es = Executors.newSingleThreadExecutor(); // 这个类中,核心线程和新建线程数都是1
        for (int i =1;i<=100;i++){
          es.execute(new Runnable() {
              @Override
              public void run() {
                  System.out.println(Thread.currentThread().getName());
              }
          });
        }
        es.shutdown();
    }
}

Callable原理,多线程执行Callable任务

public class Test01 implements Callable<Integer> {
    // 重写call 方法,这个方法:有返回值,有抛出异常
    @Override
    public Integer call() throws Exception {
        Thread.sleep(2000);
        return new Random().nextInt(10);
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 缺点:创建线程方式比较繁琐:
        // 创建线程对象:
        Test01 tt = new Test01();

        // 启动线程:
        FutureTask<Integer> ft = new FutureTask<>(tt);
        Thread t = new Thread(ft);
        t.start();

        // 返回值自己获取
        System.out.println(ft.isDone());
        Integer i = ft.get();
        System.out.println(i);
        System.out.println(ft.isDone());
    }
}

Callable最重要的底层是FutureTask

这是它的构造器,在这个类中有几个重要的属性

看了上面的图,再看看它的构造器:

 在线程执行中调用start()方法本质上是调用FutureTask的run()方法

我们在最终取值的时候利用的是get()方法 

用线程池解决上面的Callable例子 

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService es = Executors.newFixedThreadPool(3);
        for (int i = 1;i<=100;i++){
            Future<String> f = es.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Thread.sleep(2000);
                    return Thread.currentThread().getName();
                }
            });
            String s = f.get();
            System.out.println(s);
        }
        es.shutdown();
    }
}

这个方法每运行一次线程睡眠2秒,夸张的阻塞效果

优化版

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService es = Executors.newFixedThreadPool(3);
        ArrayList<Future> list = new ArrayList<>();
        for (int i = 1;i<=100;i++){
            Future<String> f = es.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Thread.sleep(2000);
                    return Thread.currentThread().getName();
                }
            });
            list.add(f);
        }
        for (Future future: list) {
            String s = (String) future.get();
            System.out.println(s);
        }
        es.shutdown();
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值