Java多线程与线程池
java_多线程_笔记

1.API1.Thread API1)Join:A线程调用B线程的Join方法,A线程阻塞,直至B线程执行完毕。
2)Thread(Runable target):注意,参数target是对象实例。
ng.class :class类实例表示正在运行的java应用程序中的类和接口。
3.JDK提供的线程池ThreadPoolExecutor 线程池类,提供三种排队策略:1)直接提交。
线程池采用无界线程池,即线程池中的线程数量没有限制(无界线程池情况适用于,线程执行时间短,例如小于1秒,并发量高的场景),工作队列的默认选项是SynchronousQueue,它将任务直接提交给线程而不保持它们。
在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败,因此会构造一个新的线程。
此策略可以避免在处理可能具有内部依赖性的请求集合时出现锁定。
直接提交通常要求无界maximumPoolSizes 以避免拒绝新提交的任务。
当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
2)无界队列,线程池数量固定,队列无限制。
使用无界队列(例如,不具有预定义容量的LinkedBlockingQueue)将导致在所有corePoolSize 线程都忙的情况下将新任务加入队列。
这样,创建的线程就不会超过corePoolSize。
(因此,maximumPoolSize 的值也就无效了。
)当每个任务完全独立于其他任务,即任务执行互不影响时,适合于使用无界队列;例如,在Web 页服务器中。
这种排队可用于处理瞬态突发请求,当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
3)有界队列,当使用有限的maximumPoolSizes 时,有界队列(如ArrayBlockingQueue)有助于防止资源耗尽,但是可能较难调整和控制。
队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。
Java多线程详解——一篇文章搞懂Java多线程

Java多线程详解——⼀篇⽂章搞懂Java多线程⽬录1. 基本概念程序(program)程序是为完成特定任务、⽤某种语⾔编写的⼀组指令的集合。
即指⼀段静态的代码(还没有运⾏起来),静态对象。
进程(process)进程是程序的⼀次执⾏过程,也就是说程序运⾏起来了,加载到了内存中,并占⽤了cpu的资源。
这是⼀个动态的过程:有⾃⾝的产⽣、存在和消亡的过程,这也是进程的⽣命周期。
进程是系统资源分配的单位,系统在运⾏时会为每个进程分配不同的内存区域。
线程(thread)进程可进⼀步细化为线程,是⼀个程序内部的执⾏路径。
若⼀个进程同⼀时间并⾏执⾏多个线程,那么这个进程就是⽀持多线程的。
线程是cpu调度和执⾏的单位,每个线程拥有独⽴的运⾏栈和程序计数器(pc),线程切换的开销⼩。
⼀个进程中的多个线程共享相同的内存单元/内存地址空间——》他们从同⼀堆中分配对象,可以访问相同的变量和对象。
这就使得相乘间通信更简便、搞笑。
但索格线程操作共享的系统资源可能就会带来安全隐患(隐患为到底哪个线程操作这个数据,可能⼀个线程正在操作这个数据,有⼀个线程也来操作了这个数据v)。
配合JVM内存结构了解(只做了解即可)class⽂件会通过类加载器加载到内存空间。
其中内存区域中每个线程都会有虚拟机栈和程序计数器。
每个进程都会有⼀个⽅法区和堆,多个线程共享同⼀进程下的⽅法区和堆。
CPU单核和多核的理解单核的CPU是⼀种假的多线程,因为在⼀个时间单元内,也只能执⾏⼀个线程的任务。
同时间段内有多个线程需要CPU去运⾏时,CPU也只能交替去执⾏多个线程中的⼀个线程,但是由于其执⾏速度特别快,因此感觉不出来。
多核的CPU才能更好的发挥多线程的效率。
对于Java应⽤程序java.exe来讲,⾄少会存在三个线程:main()主线程,gc()垃圾回收线程,异常处理线程。
如过发⽣异常时会影响主线程。
Java线程的分类:⽤户线程和守护线程Java的gc()垃圾回收线程就是⼀个守护线程守护线程是⽤来服务⽤户线程的,通过在start()⽅法前调⽤thread.setDaemon(true)可以吧⼀个⽤户线程变成⼀个守护线程。
java 通用多线程工具类代码

1. 概述在面向对象编程中,多线程技术是一项重要的技能。
而 Java 作为一种流行的编程语言,也提供了丰富的多线程工具类来帮助开发者处理并发编程。
本文将介绍一些 Java 中通用的多线程工具类及其代码示例,以帮助读者更好地理解和应用多线程技术。
2. 线程池(ThreadPool)线程池是一种重要的多线程工具类,它可以有效地管理和复用线程,提高程序的性能和响应速度。
以下是一个简单的线程池代码示例:```javaimport java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ThreadPoolExample {public static void m本人n(String[] args) {// 创建固定大小的线程池ExecutorService pool = Executors.newFixedThreadPool(5);// 提交任务for (int i = 0; i < 10; i++) {pool.execute(new Task());}// 关闭线程池pool.shutdown();}}class Task implements Runnable {public void run() {System.out.println("Thread name: " +Thread.currentThread().getName());}}```在上面的代码示例中,我们使用 Executors 类的newFixedThreadPool 方法创建一个固定大小的线程池,然后提交了10 个任务给线程池处理。
最后调用 shutdown 方法关闭线程池。
3. 信号量(Semaphore)信号量是用来控制同时访问特定资源的线程数量的类,它可以防止由于线程的过多导致的资源不足。
java中实现并发的方法

java中实现并发的方法Java是一种面向对象的编程语言,它在并发编程方面提供了多种实现方法。
并发编程指的是同时执行多个任务的能力,这在处理大量数据或高负载时非常重要。
本文将介绍Java中实现并发的几种常用方法。
1. 线程(Thread)线程是Java中最基本的并发编程方法。
通过创建多个线程,可以实现并行执行多个任务。
在Java中,可以通过两种方式创建线程:继承Thread类或实现Runnable接口。
继承Thread类需要重写run()方法,而实现Runnable接口需要实现run()方法。
通过调用start()方法启动线程,线程将在自己的独立执行路径上执行任务。
2. 线程池(ThreadPoolExecutor)线程池是一种管理和复用线程的机制,可以避免频繁创建和销毁线程的开销。
Java提供了ThreadPoolExecutor类来实现线程池。
通过创建一个线程池,可以将任务提交给线程池,线程池会自动分配线程来执行任务。
线程池还可以控制并发线程的数量,避免系统资源被过度占用。
3. Callable和FutureCallable是一个带有返回值的任务,与Runnable接口类似,但它可以返回执行结果。
Java提供了Future接口来表示异步计算的结果。
通过调用submit()方法提交Callable任务给线程池,将返回一个Future对象,可以使用该对象获取任务的执行结果。
4. 并发集合(Concurrent Collections)Java提供了一些并发安全的集合类,例如ConcurrentHashMap、ConcurrentLinkedQueue等。
这些集合类在多线程环境下使用时,可以避免出现线程安全问题。
并发集合类采用了一些特殊的数据结构和算法来保证线程安全性,能够高效地处理并发访问。
5. 锁(Lock)锁是一种同步机制,可以保证多个线程对共享资源的互斥访问。
Java提供了synchronized关键字来实现锁机制,也提供了Lock接口及其实现类来实现更加灵活的锁。
Java线程池使用和常用参数

Java线程池使⽤和常⽤参数多线程问题:1、java中为什么要使⽤多线程使⽤多线程,可以把⼀些⼤任务分解成多个⼩任务来执⾏,多个⼩任务之间互不影像,同时进⾏,这样,充分利⽤了cpu资源。
2、java中简单的实现多线程的⽅式继承Thread类,重写run⽅法;12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28class MyTread extends Thread{public void run() { System.out.println(Thread.currentThread().getName());}}实现Runable接⼝,实现run⽅法;class MyRunnable implements Runnable{ public void run() { System.out.println(Thread.currentThread().getName()); }}class ThreadTest { public static void main(String[] args) { MyTread thread = new Mythread(); thread.start(); //开启⼀个线程 MyRunnable myRunnable = new MyRunnable(); Thread runnable = new Thread(myRunnable); runnable.start(); //开启⼀个线程 }}3、java线程的状态创建:当new了⼀个线程,并没有调⽤start之前,线程处于创建状态;就绪:当调⽤了start之后,线程处于就绪状态,这是,线程调度程序还没有设置执⾏当前线程;运⾏:线程调度程序执⾏到线程时,当前线程从就绪状态转成运⾏状态,开始执⾏run⽅法⾥边的代码;阻塞:线程在运⾏的时候,被暂停执⾏(通常等待某项资源就绪后在执⾏,sleep、wait可以导致线程阻塞),这是该线程处于阻塞状态;死亡:当⼀个线程执⾏完run⽅法⾥边的代码或调⽤了stop⽅法后,该线程结束运⾏4、为什么要引⼊线程池当我们需要的并发执⾏线程数量很多时,且每个线程执⾏很短的时间就结束了,这样,我们频繁的创建、销毁线程就⼤⼤降低了⼯作效率(创建和销毁线程需要时间、资源)。
【多线程】Java线程池七个参数详解

【多线程】Java线程池七个参数详解/*** Creates a new {@code ThreadPoolExecutor} with the given initial* parameters.** @param corePoolSize the number of threads to keep in the pool, even* if they are idle, unless {@code allowCoreThreadTimeOut} is set* @param maximumPoolSize the maximum number of threads to allow in the* pool* @param keepAliveTime when the number of threads is greater than* the core, this is the maximum time that excess idle threads* will wait for new tasks before terminating.* @param unit the time unit for the {@code keepAliveTime} argument* @param workQueue the queue to use for holding tasks before they are* executed. This queue will hold only the {@code Runnable}* tasks submitted by the {@code execute} method.* @param threadFactory the factory to use when the executor* creates a new thread* @param handler the handler to use when execution is blocked* because the thread bounds and queue capacities are reached* @throws IllegalArgumentException if one of the following holds:<br>* {@code corePoolSize < 0}<br>* {@code keepAliveTime < 0}<br>* {@code maximumPoolSize <= 0}<br>* {@code maximumPoolSize < corePoolSize}* @throws NullPointerException if {@code workQueue}* or {@code threadFactory} or {@code handler} is null*/public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)⼀、corePoolSize 线程池核⼼线程⼤⼩线程池中会维护⼀个最⼩的线程数量,即使这些线程处理空闲状态,他们也不会被销毁,除⾮设置了allowCoreThreadTimeOut。
javaspringboot线程池以及多线程

javaspringboot线程池以及多线程线程和进程进程是资源分配的最⼩单位,线程是CPU调度的最⼩单位。
是不是很抽象,做个简单⽐喻,进程=⽕车,线程=车厢,线程在进程⾥运⾏(单个的车厢是⽆法运⾏的);不同进程之间数据很难共享,同⼀进程下的线程数据共享则很容易。
多线程⼀个应⽤程序有多条执⾏路径(单线程:⼀个应⽤程序只有⼀条执⾏路径)。
应⽤场景异步,有些功能⽆需同步执⾏,可以使⽤另外⼀个线程去执⾏。
多个线程共同完成⼀个事情,缩短整体执⾏时间,同时cpu也得到了充分利⽤(例如,盖房⼦垒墙,⼀个⼈需要10天,10个⼈同时做,1天左右可以完成)。
线程池什么是线程池线程池,顾名思义,是存放了⼀堆线程的池⼦/容器,并且管理线程的整个⽣命周期。
java.util.concurrent.Executors提供了⼀个 java.util.concurrent.Executor接⼝的实现⽤于创建线程池。
为什么要⽤线程池1. 减少了创建和销毁线程的次数,每个⼯作线程都可以被重复利⽤,可执⾏多个任务。
2. 可以根据系统的承受能⼒,调整线程池中⼯作线线程的数⽬,防⽌因为消耗过多的内存,⽽把服务器累趴下(每个线程需要⼤约1MB内存,线程开的越多,消耗的内存也就越⼤,最后死机)。
实现⽅式此处以springboot实现⽅式为例import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.Executor;import java.util.concurrent.ThreadPoolExecutor;/*** @author lipeiguang*/@Configuration@EnableAsyncpublic class ThreadPoolConfig {@Bean(name = "executor")public Executor getAsyncThread() {ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();//线程池维护线程的最少数量taskExecutor.setCorePoolSize(5);//线程池维护线程的最⼤数量,只有在缓冲队列满了之后才会申请超过核⼼线程数的线程taskExecutor.setMaxPoolSize(10);//缓存队列taskExecutor.setQueueCapacity(20);//允许的空闲时间,当超过了核⼼线程出之外的线程在空闲时间到达之后会被销毁taskExecutor.setKeepAliveSeconds(200);//线程名称前缀taskExecutor.setThreadNamePrefix("my-thread-");// 线程池对拒绝任务(⽆线程可⽤)的处理策略,⽬前只⽀持AbortPolicy、CallerRunsPolicy;默认为后者taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());// 调度器shutdown被调⽤时等待当前被调度的任务完成taskExecutor.setWaitForTasksToCompleteOnShutdown(true);// 等待时长taskExecutor.setAwaitTerminationSeconds(60);taskExecutor.initialize();return taskExecutor;}}其中的corePoolSize设置参考:N为cpu个数如果是CPU密集型应⽤,则线程池⼤⼩设置为N+1如果是IO密集型应⽤,则线程池⼤⼩设置为2N+1cpu个数查询⽅式:Runtime.getRuntime().availableProcessors();linux查询⽅式:cat /proc/cpuinfo| grep"processor"| wc -l使⽤线程池实现异步import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import java.util.concurrent.Executor;/*** 使⽤demo* @author lipeiguang*/@Slf4j@Api(tags = {"异步线程测试"})@RestControllerpublic class ExecutorDemo {//使⽤时通过注解/*** 如果是多线程,可以直接使⽤这个executor*/@Resource(name = TaskExecutorConstant.SALARY_TASK_EXECUTOR) private Executor executor;@Autowiredprivate ServiceDemo serviceDemo;@ApiOperation("异步测试")@GetMapping("/test/async")public String testAsync(){("主线程开始执⾏。
JAVA使用多线程(线程池)进行数据处理

JAVA使⽤多线程(线程池)进⾏数据处理*⼯作顺序:* 1)、线程池创建,准备好core数量的核⼼线程,准备接受任务* 1.1、core满了,就将再进来的任务放⼊阻塞队列中。
空闲的core就会⾃⼰去阻塞队列获取任务执⾏* 1.2、阻塞队列满了,就直接开新线程执⾏,最⼤只能开到max指定的数量* 1.3、max满了就⽤RejectedExecut ionHandler拒绝任务* 1.4、max都执⾏完成,有很多空闲.在指定的时间keepAliveTime以后,释放max-core这些线程new LinkedBlockingDeque<>(): 默认是Integer的最⼤值。
内存不够⼀个线程池core 7; max 20,queue:50,100并发进来怎么分配的;7个会⽴即得到执⾏,50个会进⼊队列,再开13个进⾏执⾏。
剩下的30个就使⽤拒绝策略。
Executors . newCachedThreadPool() core是0,所有都可回收Executors . newF ixedThreadPool()固定⼤⼩,core=max; 都不可回收Executors. newScheduledThreadPool()定时任务的线程池Executors. newSingleThreadExecutor()单线程的线程池,后台从队列⾥⾯获取任务,挨个执⾏import mons.collections.CollectionUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;import java.util.ArrayList;import java.util.List;import java.util.concurrent.*;/*** 以下是伪代码,要根据⾃⼰的实际逻辑进⾏整合*/@Servicepublic class PushProcessServiceImpl implements PushProcessService {private final static Logger logger = LoggerFactory.getLogger(PushProcessServiceImpl.class);/***每个线程更新的条数* 这表⽰每次执⾏五千条数据的推送操作*/private static final Integer LIMIT = 5000;/*** 起的线程数*/private static final Integer THREAD_NUM = 5;/*** 创建线程池** - corePoolSize:线程核⼼参数选择了5** - maximumPoolSize:最⼤线程数选择了核⼼线程数2倍数** - keepAliveTime:⾮核⼼闲置线程存活时间直接置为0** - unit:⾮核⼼线程保持存活的时间选择了 TimeUnit.SECONDS 秒** - workQueue:线程池等待队列,使⽤容量初始为100的 LinkedBlockingQueue阻塞队列** 线程池拒绝策略,采⽤了默认AbortPolicy:直接丢弃任务,抛出异常。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
重试添加当前的任务,他会自动重复调用execute()方法
• ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
• ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
线程池ThreadPoolExecutor
• handler有四个选择:
• ThreadPoolExecutor.AbortPolicy() 抛出java.util.concurrent.RejectedExecutionException异常 • ThreadPoolExecutor.CallerRunsPolicy()
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
线程池ThreadPoolExecutor
• 处理任务的优先级为: • 核心线程corePoolSize、任务队列workQueue、最大 线程maximumPoolSize,如果三者都满了,使用 handler处理被拒绝的任务。
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
线程池ThreadPoolExecutor
• 一个任务通过 execute(Runnable)方法被添加到线程 池,任务就是一个 Runnable类型的对象,任务的执行 方法就是 Runnable类型对象的run()方法。
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
线程池ThreadPoolExecutor
• 线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
Executors
• Executors有几个static方法,列出如下:
newCachedThreadPool newFixedThreadPool newSingleThreadExecutor newScheduledThreadPool newSingleThreadScheduledE xecutor 建立可以快取的Thread,每个Thread预设可 idle 60秒 包括固定数量的Thread 只有一个Thread,循序的执行指定给它的每 个任务 可排程的Thread 单一可排程的Thread
•
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
Blocking Queue
• BlockingQueue的主要方法如下:
add remove element offer poll peek put take 加入元素,如果队列是满的,则抛出IllegalStateException 返回并从队列移除元素,如果队列是空的,则抛出 NoSuchElementException 返回元素,如果队列是空的,则抛出 NoSuchElementException 加入元素并返回true,如果队列是满的,则返回false 返回并从队列移除元素,如果队列是空的,则返回null 返回元素,如果队列是空的,则返回null 加入元素,如果队列是满,就block 返回并移除元素,如果队列是空的,就block
signalAll()
• 通知目前等待中的所有执行线程,而后从上次的等待点继续执行 法。
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
Lock 与 Condition
• 参见例子Clerk.java
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
SCWCD++企业级开发课程 Java多线程与 线程池
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
目录
• Lock 与 Condition • BlockingQueue • Executors • 线程池ThreadPoolExecutor
线程池ThreadPoolExecutor
• 参见线程池例子:TestThreadPool
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
课堂练习
• 1.线程池案例练习,表迁移实现 已知表A和表A_HIS结构如下: FileName DateType Null commnets id int not null id,自增(注:A_HIS表该字段不为自增) name varchar2(60) not null 名称 type varchar2(60) not null 类型 source varchar2(60) not null 来源 create_name varchar2(60) not null 创建人姓名 desc varchar2(100) not null 描述 create_date varchar2(60) not null 创建时间(yyyy-mm-dd hh:mm:ss) month int not null 月份 • • • 2.先在表A中插入500-1000条记录 3.实现一个工作线程定时每秒插入10条进入到表A 4.实现一个线程池,定时启动一定数量的工作线程迁移表A记录到表A_HIS
Blocking Queue
• 队列(Queue)是个先前先出(First In First Out, FIFO)的数 据结构。 在JDK 5.0中新增了Blocking Queue,在多线程的情況下,如果 Blocking Queue的內容为空,而有个线程试图从Queue中取出元 素,则该线程会被Block,直到Queue有元素时才解除Block,反 过來说,如果 Blocking Queue满了,而有个线程试图再把元素插 入Queue中,则该线程会被Block,直到Queue中有元素被取走后 解除Block。
• • • • • •
corePoolSize: 线程池维护线程的最少数量 maximumPoolSize:线程池维护线程的最大数量 keepAliveTime: 线程池维护线程所允许的空闲时间 unit: 线程池维护线程所允许的空闲时间的单位 workQueue: 线程池所使用的缓冲队列 handler: 线程池对拒绝任务的处理策略
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
线程池ThreadPoolExecutor
• 当一个任务通过execute(Runnable)方法欲添加到线 程池时:
• 如果此时线程池中的数量小于corePoolSize,即使线程池中的线 程都处于空闲状态,也要创建新的线程来处理被添加的任务。 • 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。 未满,那么任务被放入缓冲队列。
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
Executors
• 有时候需要建立许多Thread来执行一些小任务,然而 频繁的建立Thread又会产生开销,因为Thread的建立 必须与操作系统交互,如果能建立一个Thread pool来 管理这些小的Thread并加以重复使用,对于系统性能 会是个很好的改善方式。
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
Executors
• • 参见例子ExecutorDemo.java 例子解析: 例子使用newFixedThreadPool方法建立Thread pool,当中包括五个可以重复使用的Thread,可以指定 Runnable对象给它,程式中会产生十个Runnable对象,由于 Thread pool中只有五个可用的Thread,所以后来建立的五个 Runnable必须等待有空空的Thread才会被执行。
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
Blocking Queue
• 课堂练习: 实现生产者消费者Blocking Queue版本
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
线程池ThreadPoolExecutor
• unit可选的参数为java.util.concurrent.TimeUnit中 的几个静态属性: • NANOSECONDS、MICROSECONDS、 MILLISECONDS、SECONDS。 • workQueue常用的有: java.util.concurrent.ArrayBlockingQueue或 java.util.concurrent.LinkedBlockingQueue
SPOTO IT人才培训机构 以伙伴关系帮助客户成功,帮助员工成功,帮助合作伙伴成功。
Lock 与 Condition
• 在java.util.concurrent.locks中新增了Lock与Condition,可以明确的在程序中进行 明确的锁与释放锁。 Lock是一个接口,其中定义了lock()、unclock()与newCondition()三种方法: