java中线程池的使用,java线程池的作用及使用方法
一、前言二。什么是线程池?三、线程池构造方法ThreadPoolExecutor构造方法的参数是什么意思?第四,模拟一个线程池总结。
00-1010为了实现并发编程,引入了进程的概念。进程相当于操作系统的一个任务。当多个进程同时执行任务时,就实现了并发编程,可以更快地执行。
但是,因为进程不够轻量级,所以创建一个进程和销毁一个进程所消耗的资源是不可忽略的。如果进程的数量很少,资源消耗是可以接受的,但是如果进程被频繁地创建和销毁。这是一笔很大的开支。
那要怎么办呢?
为了解决这个问题,人们推出了一种更轻便的工具,——螺纹。
线程也称为轻量级进程。它的创建和销毁消耗的资源比进程少。但是如果任务很多,多线程承受不了频繁的创建和销毁怎么办?然后线程池就出来解决问题了!
00-1010线程池类似于Java字符串常量池。
使用线程与不使用线程
使用线程时,直接从池中取出一个线程。当你不用线的时候,把它放在水池里。大家都知道找工作的过程是这样的。
提交书面简历面试offer当我们到了面试的最后,会出现两种情况。
是的,公司打电话通知你,offer没通过,而且一般公司不是告诉你没通过,而是根本没通知你没通过。这是因为公司可能会把你放在他们的‘人才库’里。假设该公司正在寻找50人,在秋季,它提供了50人。但实际上,只有35个人来报到。这时候剩下的15个人直接从人才库里捞出15个,直接发offer。
这时,过了一会儿,公司突然打电话通知你,你被录用了。你想来吗?这个操作相当于一个线程被使用,直接从池中取出来使用。
这是一个找工作描述线程池大概意思的例子。
00-1010 《阿里巴巴java开发手册》中指出线程资源必须通过线程池提供,不允许在应用中自行创建显示的线程。一方面,线程的创建更加规范,可以合理控制打开线程的数量;另一方面,线程的细节管理交给线程池,优化了资源成本。
类‘ThreadPoolExecutor’是Java标准库提供的一组使用线程池的类。
有四种方法可以构造ThreadPoolExecutor。它包含不同的参数,使用不同的场景。下面介绍一下参数最多的构造方法。
ThreadPoolExecutor ThreadPoolExecutor=new ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueRunnable workQueue,ThreadFactory threadFactory,RejectedExecutionHandler处理程序)
1.corepowersize核心线程数
2.maximumPoolSize最大线程数
对于核心线程数和最大线程数,你可能不太明白是什么。这里有一个员工去上班的例子。
核心线程的数量是公司里的正式员工,允许他们钓鱼一段时间。如果你发现了,你不会被解雇。(相当于线程池中的线程即使不做任何事情也不会被销毁)
最大线程数是公司正式员工和临时工的人数,但这里的临时工钓到一定时间就会被解雇。(相当于线程池中的线程被销毁)
3.keepAliveTime描述临时工可以打鱼多久。
4.unit是时间单位,即keepAliveTime的单位。
5.当5.workQueue阻塞队列时,它组织任务由线程池执行。
6.threadFactory线程创建方法。该参数用于设置不同的螺纹创建方法。
7.RejectedExecutionHandler处理程序拒绝策略。当任务队列满了,新的任务又来了。这时候我该怎么办?
(1):不需要最新的任务。
(2):我不要最老的任务。
(3):阻塞等待
(4) Swing:抛出异常
由于ThreadPoolExecutor使用起来很复杂,所以最多有七个。
参数。标准库为此又为程序员们提供了一组其他的类。相当于对ThreadPoolExecutor又进行了一层封装。
1.newFixedThreadPool
:创建出一个固定线程数量的线程池。
ExecutorService Service1 = Executors.newFixedThreadPool (20);
2.newCachedThreadPool
:创建出一个数量可变的线程池
ExecutorService Service2 = Executors.newCachedThreadPool ();
3.newSingleThreadExecutor
:创建只有一个线程的线程池
ExecutorService Service3 = Executors.newSingleThreadExecutor ();
4.newScheduledThreadPool
:创建一个能设定延时时间的线程池。
ExecutorService Service4 = Executors.newScheduledThreadPool (20);
四、模拟实现一个线程池
模拟实现一个线程池的核心操作:.:将任务加到线程池中--submit。.:使用Worker类描述一个工作线程,Runnable来描述一个任务。.:创建一个BlockingQueue阻塞队列组织所有任务。.:每个Worker要做的事情就是不停的从阻塞队列里获取任务并执行。.:指定线程池中的线程最大数目,如果超过这个数目就不要再继续创建线程了。
代码实现:
我们创建一个线程池并让它不停的创建进程打印hello
import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;/** * Created with IntelliJ IDEA. * * @Description: 模拟实现线程池的使用 */public class ThreadDemo0327_2 { public static void main (String[] args) throws IOException, InterruptedException { ThreadPoll threadPoll=new ThreadPoll (); for (int i = 0 ; i <10 ; i++) { threadPoll.submit (new Runnable () { @Override public void run () { System.out.println ("hello"); } }); } }}class Worker extends Thread{ public BlockingQueue<Runnable> queue=null; public Worker(BlockingQueue<Runnable> queue){ this.queue=queue; } @Override public void run () { //工作线程的具体逻辑 //需要从阻塞队列中取任务. while (true){ try { Runnable command=queue.take (); //通过run来执行具体任务 command.run (); }catch (InterruptedException e){ e.printStackTrace (); } } }}class ThreadPoll{ //包含一个阻塞队列,用来组织任务 public BlockingQueue<Runnable> queue=new LinkedBlockingQueue<> (); //这个list就用来存放当前的工作线程. public List<Thread> works=new ArrayList<> (); public int MAX_WORKER_COUNT=10; //通过这个方法,把任务加入到线程池中 //submit不光可以把任务放到阻塞队列中,也可以负责创建线程 public void submit(Runnable command) throws IOException, InterruptedException { if(works.size ()<MAX_WORKER_COUNT){ //如果当前工作线程的数量不足线程数目上线,就创建出新的线程 //工作线程就专门找一个类完成 //worker内部要哦能够取到队列的内容,就要把这个队列实例通过worker的构造方法传过去 Worker worker=new Worker (queue); worker.start (); works.add (worker); } queue.put (command); }}
运行效果:
可以看到,打印了10个hello。
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注盛行IT的更多内容!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。