java下线程池的实现原理

1.什么是进程,什么是线程

进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.例如QQ、微信都是进程。注:用户每启动一个进程,操作系统就会为该进程分配一个独立的内存空间。

线程:一个程序至少有一个进程,一个进程至少有一个线程.是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.线程是进程的一部分,一个进程包括多个线程。同一个进程中的多个线程之间可以并发执行,

线程:(1)线程是轻量级的进程

          (2)线程是没有独立的内存空间(地址空间)

          (3)线程是由进程创建的(寄生在进程)

          (4)一个进程可以拥有多个线程(这就是我们说的多线程编程)

          (5)线程有5种状态:新建状态(new),就绪状态(runnable),运行状态(running),阻塞状态(blocked),死亡状态(dead)

新建状态(new):当用new操作符创建一个新线程时,如new Thread(r),该线程还没有开始运行,它的当前状态为new,在线程运行之前还有一些基础工作要做。

就绪状态(可运行状态)(runnable):一旦线程调用start方法,线程处于runnable状态,等待线程调度,获取cpu 的使用权 。

运行状态(running):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。

阻塞状态(blocked):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种: 

(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

死亡状态(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

线程池:

程序的运行,其本质上,是对系统资源(CPU、内存、磁盘、网络等等)的使用。如何高效的使用这些资源是我们编程优化演进的一个方向。今天说的线程池就是一种对CPU利用的优化手段。

(1)在Java中创建线程池:

public void testThreadPool(){
     ExecutorService executorService = new ThreadPoolExecutor(1,2,60,TimeUnit.SECONDS,new ArrayBlockingQueue(10));
    for(int i = 0;i++ <20;) {
		executorService.execute(new Runnable() {
			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName());
				System.out.println("xianchengchi");
			}
		});
	}
}

(2)线程池有这些参数:corepoolsize、maximumpoolsize、keepalivetime、unit、workqueue、threadfactory、handler

corePoolSize:线程池核心线程数量

maximumPoolSize:线程池最大线程数量

keepAliverTime:当活跃线程数大于核心线程数时,空闲的多余线程最大存活时间

unit:存活时间的单位

workQueue:存放任务的队列

threadfactory:设置线程的属性,例如设置线程名等

handler:超出线程范围和队列容量的任务的处理决策

参数的作用如下图:

(3)超过(最大线程数+排队队列数)的线程,会执行一个策略(四种)(线程池拒绝策略直接抛异常RejectedExecutionException默认给的异常、自行运行也就是超过的线程有自己所在的方法运行不交给线程池运用CallerRunsPolicy、直接拒绝访问DiscardOldestPolicy(DiscardPolisy))

1、AbortPolicy:直接抛出异常

2、CallerRunsPolicy:只调用所在的线程运行任务(交给自己处理任务)

3、DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。

4、DiscardPolicy:不处理,丢弃掉。

猜你喜欢

转载自blog.csdn.net/weixin_42442847/article/details/83008073