Java多线程——线程池

1、并发队列

  • 队列:先入先出
  • 栈:先进后出

并发队列分为阻塞队列和非阻塞队列。

线程池就是阻塞队列实现的

1.1阻塞队列与非阻塞队列的区别

入队时:
	非阻塞队列:当队列满了放入数据时,放不进去,数据丢失
	阻塞队列:当队列满了放入数据时,等待队列中有数据出队时放入
出队时:
	非阻塞队列:当队列为空取出数据是,取出为null
	阻塞队列:	当队列为空取出数据是,等待队列中有数据进入再取出

1.2代码举例

1.2.1非阻塞队列——ConcurrentLinkedQueue

public static void main(String[] args) {
        //无边界队列:没有限制队列长度
        ConcurrentLinkedQueue<String> clq = new ConcurrentLinkedQueue<>();
        clq.add("java");
        clq.add("html");
        clq.add("css");
        //队列中元素的排列顺序:java,html,css
        
        System.out.println(clq.poll()); //java
        System.out.println(clq.size()); //2
        System.out.println(clq.peek()); //html
        System.out.println(clq.size()); //2 队列长度没有改变
    }

队列的add()方法是往队列末尾插入元素

poll()和peek()方法
返回值都为String
poll():获取队首元素,并移除
peek():获取队首元素,但不移除

1.2.2阻塞队列——LinkedBlockingQueue

BlockingQueue是一个接口,它的实现类有:
LinkedBlockingQueue,ArrayBlockingQueue,DelayQueue,LinkedBlockingDeque,PriorityBlockQueue

使用add添加元素

public static void main(String[] args) {
        BlockingQueue<String> bq = new LinkedBlockingQueue<>(3); //设置边界
        //入队
        bq.add("java");
        bq.add("html");
        bq.add("css");
        bq.add("mysql");
        //出队
        System.out.println(bq.poll());
        System.out.println(bq.poll());
        System.out.println(bq.poll());
        System.out.println(bq.poll());
		/* Output:
		* Exception in thread "main" java.lang.IllegalStateException: Queue full
		* /
    }

使用offer添加元素

        bq.offer("java");
        bq.offer("html");
        bq.offer("css");
        bq.offer("mysql");
       /* Output:
		* java html css null
		* / 

总结:

  • add():在不违反容量限制的情况下立即将指定的元素插入此队列末尾,成功时返回true,如果当前没有可用空间,则抛出illeglastException。
  • offer():在不违反容量限制的情况下立即将指定的元素插入此队列末尾,成功时返回true;如果当前没有可用空间,则返回false。

offer()还有一种添加方式,等待3秒后添加进队列

// Boolean  offer(String e, long timeout, TimeUnit unit) 添加元素,等待时长,单位
bq.offer("mysql", 3, TimeUnit.SECONDS);

2、线程池

2.1什么是线程池?

一个正常的线程的生命周期是从创建到死亡(创建状态–>就绪状态–>运行状态–>死亡状态)
在这里插入图片描述

2.2ThreadPoolExecutor类

在这里插入图片描述

JDK1.5后引入了内置线程池的概念

2.2线程池的分类

可缓存线程池
public static void main(String[] args) {
        ExecutorService es = Executors.newCachedThreadPool();
        for(int i=0;i<=100;i++){
            es.execute(new Runnable(){
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }
        es.shutdown();
    }

可缓存的线程池
* newCachedThreadPool
* 构造方法:new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,new SynchronousQueue());
* 可看成是无边界的线程池 最多能容纳(Integer的最大值)这么多线程

定长线程池
public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(3); //核心线程数 = 最大线程数 = 3
        for(int i=0;i<=100;i++){
            es.execute(new Runnable(){
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }
        es.shutdown();
    }

定长的线程池
* newFixedThreadPool(int nThreads);
* 构造方法:new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue());
* 核心线程数=最大线程数=nThreads

定时线程池
public static void main(String[] args) {
        ScheduledExecutorService ses = Executors.newScheduledThreadPool(3);//核心线程数
        for(int i=0;i<100;i++){
            ses.schedule(new Runnable(){

                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            },3, TimeUnit.SECONDS);
        }
        ses.shutdown();
    }

定时线程池
* ScheduledThreadPoolExecutor extend ThreadPoolExecutors
* 传入参数=核心线程数

 public ThreadPoolExecutor(int corePoolSize,
                                    int maximumPoolSize,
                                    long keepAliveTime,
                                    TimeUnit unit,
                                    BlockingQueue<Runnable> workQueue) {
              this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
                   Executors.defaultThreadFactory(), defaultHandler);
}
单例线程池
public static void main(String[] args) {
        ExecutorService es = Executors.newSingleThreadExecutor();
        for(int i =0;i<=100;i++){
            es.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }
        es.shutdown();
    }
  • 单例线程池
  • newSingleThreadExecutor
  • 当前线程池只有一个线程
  • 核心线程=最大线程=1
  • 构造方法 new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue()));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值