「java线程池中」java线程池中核心线程会被回收吗

博主:adminadmin 2023-03-20 17:05:09 378

今天给各位分享java线程池中的知识,其中也会对java线程池中核心线程会被回收吗进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

java线程池线程不足会出现线程交叉吗

您好!Java线程池中线程不足不会导致线程交叉。线程交叉的情况是指两个或多个线程同时执行同一个代码块的情况,从而导致数据竞争、死锁等问题。

Java线程池中,如果所有线程都在执行任务,则新的任务会等待,直到线程池中有空闲线程为止。如果线程池中没有可用线程,则新的任务将被放入任务队列中等待,直到有可用线程为止。因此,线程池中的任务是按顺序依次执行的,不会发生线程交叉的情况。

当然,如果在代码实现中没有正确使用同步措施,可能会出现线程交叉的情况,但这不是由于线程池中线程不足导致的。为避免线程交叉,应该在代码中正确地使用同步措施,如使用锁或原子操作等。

Java实现通用线程池

线程池通俗的描述就是预先创建若干空闲线程 等到需要用多线程去处理事务的时候去唤醒某些空闲线程执行处理任务 这样就省去了频繁创建线程的时间 因为频 繁创建线程是要耗费大量的CPU资源的 如果一个应用程序需要频繁地处理大量并发事务 不断的创建销毁线程往往会大大地降低系统的效率 这时候线程池就派 上用场了

本文旨在使用Java语言编写一个通用的线程池 当需要使用线程池处理事务时 只需按照指定规范封装好事务处理对象 然后用已有的线程池对象去自动选择空 闲线程自动调用事务处理对象即可 并实现线程池的动态修改(修改当前线程数 最大线程数等) 下面是实现代码

//ThreadTask java

package polarman threadpool;

/** *//**

*线程任务

* @author ryang

*

*/

public interface ThreadTask {

public void run();

}

//PooledThread java

package polarman threadpool;

import java util Collection; import java util Vector;

/** *//**

*接受线程池管理的线程

* @author ryang

*

*/

public class PooledThread extends Thread {

protected Vector tasks = new Vector();

protected boolean running = false;

protected boolean stopped = false;

protected boolean paused = false;

protected boolean killed = false;

private ThreadPool pool;

public PooledThread(ThreadPool pool) { this pool = pool;

}

public void putTask(ThreadTask task) { tasks add(task);

}

public void putTasks(ThreadTask[] tasks) { for(int i= ; itasks length; i++) this tasks add(tasks[i]);

}

public void putTasks(Collection tasks) { this tasks addAll(tasks);

}

protected ThreadTask popTask() { if(tasks size() ) return (ThreadTask)tasks remove( );

else

return null;

}

public boolean isRunning() {

return running;

}

public void stopTasks() {

stopped = true;

}

public void stopTasksSync() {

stopTasks();

while(isRunning()) { try {

sleep( );

} catch (InterruptedException e) {

}

}

}

public void pauseTasks() {

paused = true;

}

public void pauseTasksSync() {

pauseTasks();

while(isRunning()) { try {

sleep( );

} catch (InterruptedException e) {

}

}

}

public void kill() { if(!running)

interrupt();

else

killed = true;

}

public void killSync() {

kill();

while(isAlive()) { try {

sleep( );

} catch (InterruptedException e) {

}

}

}

public synchronized void startTasks() {

running = true;

this notify();

}

public synchronized void run() { try { while(true) { if(!running || tasks size() == ) { pool notifyForIdleThread(); //System out println(Thread currentThread() getId() + : 空闲 ); this wait(); }else {

ThreadTask task;

while((task = popTask()) != null) { task run(); if(stopped) {

stopped = false;

if(tasks size() ) { tasks clear(); System out println(Thread currentThread() getId() + : Tasks are stopped );

break;

}

}

if(paused) {

paused = false;

if(tasks size() ) { System out println(Thread currentThread() getId() + : Tasks are paused );

break;

}

}

}

running = false;

}

if(killed) {

killed = false;

break;

}

}

}catch(InterruptedException e) {

return;

}

//System out println(Thread currentThread() getId() + : Killed );

}

}

//ThreadPool java

package polarman threadpool;

import java util Collection; import java util Iterator; import java util Vector;

/** *//**

*线程池

* @author ryang

*

*/

public class ThreadPool {

protected int maxPoolSize;

protected int initPoolSize;

protected Vector threads = new Vector();

protected boolean initialized = false;

protected boolean hasIdleThread = false;

public ThreadPool(int maxPoolSize int initPoolSize) { this maxPoolSize = maxPoolSize; this initPoolSize = initPoolSize;

}

public void init() {

initialized = true;

for(int i= ; iinitPoolSize; i++) {

PooledThread thread = new PooledThread(this);

thread start(); threads add(thread);

}

//System out println( 线程池初始化结束 线程数= + threads size() + 最大线程数= + maxPoolSize);

}

public void setMaxPoolSize(int maxPoolSize) { //System out println( 重设最大线程数 最大线程数= + maxPoolSize); this maxPoolSize = maxPoolSize;

if(maxPoolSize getPoolSize())

setPoolSize(maxPoolSize);

}

/** *//**

*重设当前线程数

* 若需杀掉某线程 线程不会立刻杀掉 而会等到线程中的事务处理完成* 但此方法会立刻从线程池中移除该线程 不会等待事务处理结束

* @param size

*/

public void setPoolSize(int size) { if(!initialized) {

initPoolSize = size;

return;

}else if(size getPoolSize()) { for(int i=getPoolSize(); isize imaxPoolSize; i++) {

PooledThread thread = new PooledThread(this);

thread start(); threads add(thread);

}

}else if(size getPoolSize()) { while(getPoolSize() size) { PooledThread th = (PooledThread)threads remove( ); th kill();

}

}

//System out println( 重设线程数 线程数= + threads size());

}

public int getPoolSize() { return threads size();

}

protected void notifyForIdleThread() {

hasIdleThread = true;

}

protected boolean waitForIdleThread() {

hasIdleThread = false;

while(!hasIdleThread getPoolSize() = maxPoolSize) { try { Thread sleep( ); } catch (InterruptedException e) {

return false;

}

}

return true;

}

public synchronized PooledThread getIdleThread() { while(true) { for(Iterator itr=erator(); itr hasNext();) { PooledThread th = (PooledThread)itr next(); if(!th isRunning())

return th;

}

if(getPoolSize() maxPoolSize) {

PooledThread thread = new PooledThread(this);

thread start(); threads add(thread);

return thread;

}

//System out println( 线程池已满 等待 );

if(waitForIdleThread() == false)

return null;

}

}

public void processTask(ThreadTask task) {

PooledThread th = getIdleThread();

if(th != null) { th putTask(task); th startTasks();

}

}

public void processTasksInSingleThread(ThreadTask[] tasks) {

PooledThread th = getIdleThread();

if(th != null) { th putTasks(tasks); th startTasks();

}

}

public void processTasksInSingleThread(Collection tasks) {

PooledThread th = getIdleThread();

if(th != null) { th putTasks(tasks); th startTasks();

}

}

}

下面是线程池的测试程序

//ThreadPoolTest java

import java io BufferedReader; import java io IOException; import java io InputStreamReader;

import polarman threadpool ThreadPool; import polarman threadpool ThreadTask;

public class ThreadPoolTest {

public static void main(String[] args) { System out println( quit 退出 ); System out println( task A 启动任务A 时长为 秒 ); System out println( size 设置当前线程池大小为 ); System out println( max 设置线程池最大线程数为 ); System out println();

final ThreadPool pool = new ThreadPool( ); pool init();

Thread cmdThread = new Thread() { public void run() {

BufferedReader reader = new BufferedReader(new InputStreamReader(System in));

while(true) { try { String line = reader readLine(); String words[] = line split( ); if(words[ ] equalsIgnoreCase( quit )) { System exit( ); }else if(words[ ] equalsIgnoreCase( size ) words length = ) { try { int size = Integer parseInt(words[ ]); pool setPoolSize(size); }catch(Exception e) {

}

}else if(words[ ] equalsIgnoreCase( max ) words length = ) { try { int max = Integer parseInt(words[ ]); pool setMaxPoolSize(max); }catch(Exception e) {

}

}else if(words[ ] equalsIgnoreCase( task ) words length = ) { try { int timelen = Integer parseInt(words[ ]); SimpleTask task = new SimpleTask(words[ ] timelen * ); pool processTask(task); }catch(Exception e) {

}

}

} catch (IOException e) { e printStackTrace();

}

}

}

};

cmdThread start();

/**//*

for(int i= ; i ; i++){

SimpleTask task = new SimpleTask( Task + i (i+ )* ); pool processTask(task);

}*/

}

}

class SimpleTask implements ThreadTask {

private String taskName;

private int timeLen;

public SimpleTask(String taskName int timeLen) { this taskName = taskName; this timeLen = timeLen;

}

public void run() { System out println(Thread currentThread() getId() +

: START TASK + taskName + );

try { Thread sleep(timeLen); } catch (InterruptedException e) {

}

System out println(Thread currentThread() getId() +

: END TASK + taskName + );

}

}

使用此线程池相当简单 下面两行代码初始化线程池

ThreadPool pool = new ThreadPool( ); pool init();

要处理的任务实现ThreadTask 接口即可(如测试代码里的SimpleTask) 这个接口只有一个方法run()

两行代码即可调用

lishixinzhi/Article/program/Java/hx/201311/27203

Java线程池中的核心线程是如何被重复利用的

Java线程池中的核心线程是如何被重复利用的?

引言

在Java开发中,经常需要创建线程去执行一些任务,实现起来也非常方便,但如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。此时,我们很自然会想到使用线程池来解决这个问题。

使用线程池的好处:

降低资源消耗。java中所有的池化技术都有一个好处,就是通过复用池中的对象,降低系统资源消耗。设想一下如果我们有n多个子任务需要执行,如果我们为每个子任务都创建一个执行线程,而创建线程的过程是需要一定的系统消耗的,最后肯定会拖慢整个系统的处理速度。而通过线程池我们可以做到复用线程,任务有多个,但执行任务的线程可以通过线程池来复用,这样减少了创建线程的开销,系统资源利用率得到了提升。

降低管理线程的难度。多线程环境下对线程的管理是最容易出现问题的,而线程池通过框架为我们降低了管理线程的难度。我们不用再去担心何时该销毁线程,如何最大限度的避免多线程的资源竞争。这些事情线程池都帮我们代劳了。

提升任务处理速度。线程池中长期驻留了一定数量的活线程,当任务需要执行时,我们不必先去创建线程,线程池会自己选择利用现有的活线程来处理任务。

很显然,线程池一个很显著的特征就是“长期驻留了一定数量的活线程”,避免了频繁创建线程和销毁线程的开销,那么它是如何做到的呢?我们知道一个线程只要执行完了run()方法内的代码,这个线程的使命就完成了,等待它的就是销毁。既然这是个“活线程”,自然是不能很快就销毁的。为了搞清楚这个“活线程”是如何工作的,下面通过追踪源码来看看能不能解开这个疑问。

分析方法

在分析源码之前先来思考一下要怎么去分析,源码往往是比较复杂的,如果知识储备不够丰厚,很有可能会读不下去,或者读岔了。一般来讲要时刻紧跟着自己的目标来看代码,跟目标关系不大的代码可以不理会它,一些异常的处理也可以暂不理会,先看正常的流程。就我们现在要分析的源码而言,目标就是看看线程是如何被复用的。那么对于线程池的状态的管理以及非正常状态下的处理代码就可以不理会,具体来讲,在ThreadPollExcutor类中,有一个字段 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); 是对线程池的运行状态和线程池中有效线程的数量进行控制的, 它包含两部分信息: 线程池的运行状态 (runState) 和线程池内有效线程的数量 (workerCount),还有几个对ctl进行计算的方法:

// 获取运行状态

private static int runStateOf(int c)     { return c ~CAPACITY; }

// 获取活动线程数

private static int workerCountOf(int c)  { return c CAPACITY; }123456

以上两个方法在源码中经常用到,结合我们的目标,对运行状态的一些判断及处理可以不用去管,而对当前活动线程数要加以关注等等。

下面将遵循这些原则来分析源码。

解惑

当我们要向线程池添加一个任务时是调用ThreadPollExcutor对象的execute(Runnable command)方法来完成的,所以先来看看ThreadPollExcutor类中的execute(Runnable command)方法的源码:

public void execute(Runnable command) {

   if (command == null)

       throw new NullPointerException();

   int c = ctl.get();

   if (workerCountOf(c) corePoolSize) {

       if (addWorker(command, true))

           return;

       c = ctl.get();

   }

   if (isRunning(c) workQueue.offer(command)) {

       int recheck = ctl.get();

       if (! isRunning(recheck) remove(command))

           reject(command);

       else if (workerCountOf(recheck) == 0)

           addWorker(null, false);

   }

   else if (!addWorker(command, false))

       reject(command);

}123456789101112131415161718192021

按照我们在分析方法中提到的一些原则,去掉一些相关性不强的代码,看看核心代码是怎样的。

// 为分析而简化后的代码

public void execute(Runnable command) {

   int c = ctl.get();

   if (workerCountOf(c) corePoolSize) {

       // 如果当前活动线程数小于corePoolSize,则新建一个线程放入线程池中,并把任务添加到该线程中

       if (addWorker(command, true))

           return;

       c = ctl.get();

   }

   // 如果当前活动线程数大于等于corePoolSize,则尝试将任务放入缓存队列

   if (workQueue.offer(command)) {

       int recheck = ctl.get();

       if (workerCountOf(recheck) == 0)

           addWorker(null, false);

   }else {

       // 缓存已满,新建一个线程放入线程池,并把任务添加到该线程中(此时新建的线程相当于非核心线程)

       addWorker(command, false)

   }

}12345678910111213141516171819202122

这样一看,逻辑应该清晰很多了。

如果 当前活动线程数 指定的核心线程数,则创建并启动一个线程来执行新提交的任务(此时新建的线程相当于核心线程);

如果 当前活动线程数 = 指定的核心线程数,且缓存队列未满,则将任务添加到缓存队列中;

如果 当前活动线程数 = 指定的核心线程数,且缓存队列已满,则创建并启动一个线程来执行新提交的任务(此时新建的线程相当于非核心线程);

接下来看 addWorker(Runnable firstTask, boolean core)方法

private boolean addWorker(Runnable firstTask, boolean core) {

   retry:

   for (;;) {

       int c = ctl.get();

       int rs = runStateOf(c);

       // Check if queue empty only if necessary.

       if (rs = SHUTDOWN

           ! (rs == SHUTDOWN

              firstTask == null

              ! workQueue.isEmpty()))

           return false;

       for (;;) {

           int wc = workerCountOf(c);

           if (wc = CAPACITY ||

               wc = (core ? corePoolSize : maximumPoolSize))

               return false;

           if (compareAndIncrementWorkerCount(c))

               break retry;

           c = ctl.get();  // Re-read ctl

           if (runStateOf(c) != rs)

               continue retry;

           // else CAS failed due to workerCount change; retry inner loop

       }

   }

   boolean workerStarted = false;

   boolean workerAdded = false;

   Worker w = null;

   try {

       w = new Worker(firstTask);

       final Thread t = w.thread;

       if (t != null) {

           final ReentrantLock mainLock = this.mainLock;

           mainLock.lock();

           try {

               // Recheck while holding lock.

               // Back out on ThreadFactory failure or if

               // shut down before lock acquired.

               int rs = runStateOf(ctl.get());

               if (rs SHUTDOWN ||

                   (rs == SHUTDOWN firstTask == null)) {

                   if (t.isAlive()) // precheck that t is startable

                       throw new IllegalThreadStateException();

                   workers.add(w);

                   int s = workers.size();

                   if (s largestPoolSize)

                       largestPoolSize = s;

                   workerAdded = true;

               }

           } finally {

               mainLock.unlock();

           }

           if (workerAdded) {

               t.start();

               workerStarted = true;

           }

       }

   } finally {

       if (! workerStarted)

           addWorkerFailed(w);

   }

   return workerStarted;

}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

同样,我们也来简化一下:

// 为分析而简化后的代码

private boolean addWorker(Runnable firstTask, boolean core) {

   int wc = workerCountOf(c);

   if (wc = (core ? corePoolSize : maximumPoolSize))

       // 如果当前活动线程数 = 指定的核心线程数,不创建核心线程

       // 如果当前活动线程数 = 指定的最大线程数,不创建非核心线程  

       return false;

   boolean workerStarted = false;

   boolean workerAdded = false;

   Worker w = null;

   try {

       // 新建一个Worker,将要执行的任务作为参数传进去

       w = new Worker(firstTask);

       final Thread t = w.thread;

       if (t != null) {

           workers.add(w);

           workerAdded = true;

           if (workerAdded) {

               // 启动刚刚新建的那个worker持有的线程,等下要看看这个线程做了啥

               t.start();

               workerStarted = true;

           }

       }

   } finally {

       if (! workerStarted)

           addWorkerFailed(w);

   }

   return workerStarted;

}1234567891011121314151617181920212223242526272829303132

看到这里,我们大概能猜测到,addWorker方法的功能就是新建一个线程并启动这个线程,要执行的任务应该就是在这个线程中执行。为了证实我们的这种猜测需要再来看看Worker这个类。

private final class Worker

   extends AbstractQueuedSynchronizer

   implements Runnable{

   // ....

}

Worker(Runnable firstTask) {

   setState(-1); // inhibit interrupts until runWorker

   this.firstTask = firstTask;

   this.thread = getThreadFactory().newThread(this);

}123456789101112

从上面的Worker类的声明可以看到,它实现了Runnable接口,以及从它的构造方法中可以知道待执行的任务赋值给了它的变量firstTask,并以它自己为参数新建了一个线程赋值给它的变量thread,那么运行这个线程的时候其实就是执行Worker的run()方法,来看一下这个方法:

   public void run() {

       runWorker(this);

   }

   final void runWorker(Worker w) {

   Thread wt = Thread.currentThread();

   Runnable task = w.firstTask;

   w.firstTask = null;

   w.unlock(); // allow interrupts

   boolean completedAbruptly = true;

   try {

       while (task != null || (task = getTask()) != null) {

           w.lock();

           // If pool is stopping, ensure thread is interrupted;

           // if not, ensure thread is not interrupted.  This

           // requires a recheck in second case to deal with

           // shutdownNow race while clearing interrupt

           if ((runStateAtLeast(ctl.get(), STOP) ||

                (Thread.interrupted()

                 runStateAtLeast(ctl.get(), STOP)))

               !wt.isInterrupted())

               wt.interrupt();

           try {

               beforeExecute(wt, task);

               Throwable thrown = null;

               try {

                   task.run();

               } catch (RuntimeException x) {

                   thrown = x; throw x;

               } catch (Error x) {

                   thrown = x; throw x;

               } catch (Throwable x) {

                   thrown = x; throw new Error(x);

               } finally {

                   afterExecute(task, thrown);

               }

           } finally {

               task = null;

               w.completedTasks++;

               w.unlock();

           }

       }

       completedAbruptly = false;

   } finally {

       processWorkerExit(w, completedAbruptly);

   }

}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

在run()方法中只调了一下 runWorker(this) 方法,再来简化一下这个 runWorker() 方法

// 为分析而简化后的代码

final void runWorker(Worker w) {

   Runnable task = w.firstTask;

   w.firstTask = null;

   while (task != null || (task = getTask()) != null) {

           try {

               task.run();

           } finally {

               task = null;

           }

       }

}12345678910111213

很明显,runWorker()方法里面执行了我们新建Worker对象时传进去的待执行的任务,到这里为止貌似这个worker的run()方法就执行完了,既然执行完了那么这个线程也就没用了,只有等待虚拟机销毁了。那么回顾一下我们的目标:Java线程池中的核心线程是如何被重复利用的?好像并没有重复利用啊,新建一个线程,执行一个任务,然后就结束了,销毁了。没什么特别的啊,难道有什么地方漏掉了,被忽略了?再仔细看一下runWorker()方法的代码,有一个while循环,当执行完firstTask后task==null了,那么就会执行判断条件 (task = getTask()) != null,我们假设这个条件成立的话,那么这个线程就不止只执行一个任务了,可以执行多个任务了,也就实现了重复利用了。答案呼之欲出了,接着看getTask()方法

private Runnable getTask() {

   boolean timedOut = false; // Did the last poll() time out?

   for (;;) {

       int c = ctl.get();

       int rs = runStateOf(c);

       // Check if queue empty only if necessary.

       if (rs = SHUTDOWN (rs = STOP || workQueue.isEmpty())) {

           decrementWorkerCount();

           return null;

       }

       int wc = workerCountOf(c);

       // Are workers subject to culling?

       boolean timed = allowCoreThreadTimeOut || wc corePoolSize;

       if ((wc maximumPoolSize || (timed timedOut))

            (wc 1 || workQueue.isEmpty())) {

           if (compareAndDecrementWorkerCount(c))

               return null;

           continue;

       }

       try {

           Runnable r = timed ?

               workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :

               workQueue.take();

           if (r != null)

               return r;

           timedOut = true;

       } catch (InterruptedException retry) {

           timedOut = false;

       }

   }

}1234567891011121314151617181920212223242526272829303132333435363738

老规矩,简化一下代码来看:

// 为分析而简化后的代码

private Runnable getTask() {

   boolean timedOut = false;

   for (;;) {

       int c = ctl.get();

       int wc = workerCountOf(c);

       // timed变量用于判断是否需要进行超时控制。

       // allowCoreThreadTimeOut默认是false,也就是核心线程不允许进行超时;

       // wc corePoolSize,表示当前线程池中的线程数量大于核心线程数量;

       // 对于超过核心线程数量的这些线程,需要进行超时控制

       boolean timed = allowCoreThreadTimeOut || wc corePoolSize;

       if (timed timedOut) {

           // 如果需要进行超时控制,且上次从缓存队列中获取任务时发生了超时,那么尝试将workerCount减1,即当前活动线程数减1,

           // 如果减1成功,则返回null,这就意味着runWorker()方法中的while循环会被退出,其对应的线程就要销毁了,也就是线程池中少了一个线程了

           if (compareAndDecrementWorkerCount(c))

               return null;

           continue;

       }

       try {

           Runnable r = timed ?

               workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :

               workQueue.take();

           // 注意workQueue中的poll()方法与take()方法的区别

           //poll方式取任务的特点是从缓存队列中取任务,最长等待keepAliveTime的时长,取不到返回null

           //take方式取任务的特点是从缓存队列中取任务,若队列为空,则进入阻塞状态,直到能取出对象为止

           if (r != null)

               return r;

           timedOut = true;

       } catch (InterruptedException retry) {

           timedOut = false;

       }

   }

}123456789101112131415161718192021222324252627282930313233343536373839

从以上代码可以看出,getTask()的作用是

如果当前活动线程数大于核心线程数,当去缓存队列中取任务的时候,如果缓存队列中没任务了,则等待keepAliveTime的时长,此时还没任务就返回null,这就意味着runWorker()方法中的while循环会被退出,其对应的线程就要销毁了,也就是线程池中少了一个线程了。因此只要线程池中的线程数大于核心线程数就会这样一个一个地销毁这些多余的线程。

如果当前活动线程数小于等于核心线程数,同样也是去缓存队列中取任务,但当缓存队列中没任务了,就会进入阻塞状态,直到能取出任务为止,因此这个线程是处于阻塞状态的,并不会因为缓存队列中没有任务了而被销毁。这样就保证了线程池有N个线程是活的,可以随时处理任务,从而达到重复利用的目的。

小结

通过以上的分析,应该算是比较清楚地解答了“线程池中的核心线程是如何被重复利用的”这个问题,同时也对线程池的实现机制有了更进一步的理解:

当有新任务来的时候,先看看当前的线程数有没有超过核心线程数,如果没超过就直接新建一个线程来执行新的任务,如果超过了就看看缓存队列有没有满,没满就将新任务放进缓存队列中,满了就新建一个线程来执行新的任务,如果线程池中的线程数已经达到了指定的最大线程数了,那就根据相应的策略拒绝任务。

当缓存队列中的任务都执行完了的时候,线程池中的线程数如果大于核心线程数,就销毁多出来的线程,直到线程池中的线程数等于核心线程数。此时这些线程就不会被销毁了,它们一直处于阻塞状态,等待新的任务到来。

注意: 

本文所说的“核心线程”、“非核心线程”是一个虚拟的概念,是为了方便描述而虚拟出来的概念,在代码中并没有哪个线程被标记为“核心线程”或“非核心线程”,所有线程都是一样的,只是当线程池中的线程多于指定的核心线程数量时,会将多出来的线程销毁掉,池中只保留指定个数的线程。那些被销毁的线程是随机的,可能是第一个创建的线程,也可能是最后一个创建的线程,或其它时候创建的线程。一开始我以为会有一些线程被标记为“核心线程”,而其它的则是“非核心线程”,在销毁多余线程的时候只销毁那些“非核心线程”,而“核心线程”不被销毁。这种理解是错误的。

另外还有一个重要的接口 BlockingQueue 值得去了解,它定义了一些入队出队同步操作的方法,还可以阻塞,作用很大。

典型Java线程池的代码及其各部分功能介绍

( )根据xml文件来管理线程池的最大最小线程数( )对线程池通过Timer定期扫描以防止线程未激活 ( )通过某一个变量(本程序中是freeThreadCount)来得到空闲线程的数目 一 配置xml(listen xml)是 ?xml version= encoding= UTF ?configConsumeThreadPoolminPools /minPools ! 线程池最小线程 maxPools /maxPools! 线程池最大线程 checkThreadPeriod /checkThreadPeriod ! 检查线程池中线程的周期 分钟 /ConsumeThreadPool/config 二 对于ConsumeThreadPoolPara的javabean: import java io *;public class ConsumeThreadPoolPara implements Serializable{private int minPools;private int maxPools;private int checkThreadPeriod;public int getMinPools(){return minPools;}public int getMaxPools(){return maxPools;}public int getCheckThreadPeriod(){return checkThreadPeriod;}public void setMinPools(int minPools){this minPools = minPools;}public void setMaxPools(int maxPools){this maxPools = maxPools;}public void setCheckThreadPeriod(int checkThreadPeriod){this checkThreadPeriod = checkThreadPeriod;}public String toString(){return minPools+ + maxPools+ +checkThreadPeriod;}public ConsumeThreadPoolPara() {}public static void main(String[] args) {ConsumeThreadPoolPara consumeThreadPool = new ConsumeThreadPoolPara();}} 三 解析xml程序代码(生成ConsumeThreadPoolPara) 使用jdom解析 import jdom *;import jdom input SAXBuilder;import java io *;import java util *;public class ParseConfig {static Hashtable Listens = null;static ConnPara connpara = null;static ConsumeThreadPoolPara consumeThreadPoolPara = null;private static String configxml = listen xml ;static{getConsumeThreadPoolPara(); //得到消费的线程池的参数}/*** 装载文档* @return 返回根结点* @throws JDOMException*/public static Element loadDocument() throws JDOMException{SAXBuilder parser = new SAXBuilder(); // 新建立构造器try {Document document = parser build(configxml);Element root = document getRootElement();return root;}catch(JDOMException e){logger error( listen xml文件格式非法! );throw new JDOMException();}}public static ConsumeThreadPoolPara getConsumeThreadPoolPara(){if(consumeThreadPoolPara ==null){try {Element root = loadDocument();Element consumeThreadPool = root getChild( ConsumeThreadPool );if (consumeThreadPool != null) { //代表有数据库配置consumeThreadPoolPara = new ConsumeThreadPoolPara();Element minPools = consumeThreadPool getChild( minPools );consumeThreadPoolPara setMinPools(Integer parseInt(minPools getTextTrim()));Element maxPools = consumeThreadPool getChild( maxPools );consumeThreadPoolPara setMaxPools(Integer parseInt(maxPools getTextTrim()));Element checkThreadPeriod = consumeThreadPool getChild( checkThreadPeriod );consumeThreadPoolPara setCheckThreadPeriod(Integer parseInt(checkThreadPeriod getTextTrim()));}}catch (JDOMException e) {}}return consumeThreadPoolPara;}} 四 线程池源代码 import java util *;/*** pTitle: 线程池/p* pDescription: 采集消费模块/p* pCopyright: Copyright (c) /p* pCompany: /p* @author 张荣斌* @version */public class ThreadPool {private static int minPools = ; //最小连接池数目private static int maxPools = ; //最大连接池数目private static int checkThreadPeriod = ; //检查连接池的周期ArrayList m_ThreadList; //工作线程列表LinkedList m_RunList = null; //工作任务列表int totalThread = ; //总线程数static int freeThreadCount = ; //未被使用的线程数目private java util Timer timer = null; //定时器static Object o = new Object();static{ //先初始化线程池的参数ConsumeThreadPoolPara consumeThreadPoolPara = ParseConfig getConsumeThreadPoolPara();if(consumeThreadPoolPara!=null){minPools = consumeThreadPoolPara getMinPools();maxPools = consumeThreadPoolPara getMaxPools();checkThreadPeriod = consumeThreadPoolPara getCheckThreadPeriod()* * ;}}public void setMinPools(int minPools){this minPools = minPools;}public void setMaxPools(int maxPools){this maxPools = maxPools;}public void setCheckThreadPeriod(int checkThreadPeriod){this checkThreadPeriod = checkThreadPeriod;}public ThreadPool() {m_ThreadList=new ArrayList();m_RunList=new LinkedList();for(int i= ;iminPools;i++){WorkerThread temp=new WorkerThread();totalThread = totalThread + ;m_ThreadList add(temp);temp start();try{Thread sleep( );}catch(Exception e){}}timer = new Timer(true); //启动定时器timer schedule(new CheckThreadTask(this) checkThreadPeriod);}/*** 当有一个工作来的时候启动线程池的线程* 当空闲线程数为 的时候 看总线程是否小于最大线程池的数目 就new一个新的线程 否则sleep 直到有空闲线程为止;* 当空闲线程不为 则将任务丢给空闲线程去完成* @param work*/public synchronized void run(String work){if (freeThreadCount == ) {if(totalThreadmaxPools){WorkerThread temp = new WorkerThread();totalThread = totalThread + ;m_ThreadList add(temp);temp start();synchronized(m_RunList){m_RunList add(work);m_RunList notify();}}else{while (freeThreadCount == ) {try {Thread sleep( );}catch (InterruptedException e) {}}synchronized(m_RunList){m_RunList add(work);m_RunList notify();}}} else {synchronized(m_RunList){m_RunList add(work);m_RunList notify();}}}/*** 检查所有的线程的有效性*/public synchronized void checkAllThreads() {Iterator lThreadIterator = erator();while (lThreadIterator hasNext()) { //逐个遍厉WorkerThread lTestThread = (WorkerThread) lThreadIterator next();if (! (lTestThread isAlive())) { //如果处在非活动状态时lTestThread = new WorkerThread(); //重新生成个线程lTestThread start(); //启动}}}/*** 打印调试信息*/public void printDebugInfo(){System out println( totalThread= +totalThread);System out println( m_ThreadList size()= +m_ThreadList size());}/**** pTitle: 工作线程类/p* @author 张荣斌* @version */class WorkerThread extends Thread{boolean running = true;String work;public void run(){while(running){synchronized(o){freeThreadCount++;}synchronized(m_RunList){while(m_RunList size() == ){try{m_RunList wait();if(!running) return;}catch(InterruptedException e){} lishixinzhi/Article/program/Java/gj/201311/27379

什么是java线程池

多线程是为了能够让计算机资源合理的分配,对于处理不同的任务创建不同的线程进行处理,但是计算机创建一个线程或者销毁一个线程所花费的也是比较昂贵的,有时候需要同时处理的事情比较多,就需要我们频繁的进行线程的创建和销毁,这样花费的时间也是比较多的。为了解决这一问题,我们就可以引用线程池的概念。

所谓线程池就是将线程集中管理起来,当需要线程的时候,可以从线程池中获取空闲的线程,这样可以减少线程的频繁创建与销毁,节省很大的时间和减少很多不必要的操作。

在java中提供了ThreadPoolExecutor类来进行线程的管理,这个类继承于AbstractExecutorService,而AbstractExecutorService实现了ExecutorService接口,我们可以使用ThreadPoolExecutor来进行线程池的创建。

在ThreadPoolExecutor的构造方法中,有多个参数,可以配置不同的参数来进行优化。这个类的源码构造方法为:

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)其中每个参数代表的意义分别为

corePoolSize : 线程池中的核心线程数量,当线程池中当前的线程数小于这个配置的时候,如果有一个新的任务到来,即使线程池中还存在空闲状态的线程,程序也会继续创建一个新的线程放进线程池当中

maximumPoolSize: 线程池中的线程最大数量

keepAliveTime:当线程池中的线程数量大于配置的核心线程数量(corePoolSize)的时候,如果当前有空闲的线程,则当这个空闲线程可以存在的时间,如果在keepAliveTime这个时间点内没有新的任务使用这个线程,那么这个线程将会结束,核心线程不会结束,但是如果配置了allowCoreThreadTimeOut = true,则当空闲时间超过keepAliveTime之后,线程也会被结束调,默认allowCoreThreadTimeOut = false,即表示默认情况下,核心线程会一直存在于线程池当中。

unit : 空闲线程保持连接时间(keepAliveTime)的时间单位

workQueue:阻塞的任务队列,用来保存等待需要执行的任务。

threadFactory :线程工厂,可以根据自己的需求去创建线程的对象,设置线程的名称,优先级等属性信息。

handler:当线程池中存在的线程数超过设置的最大值之后,新的任务就会被拒绝,可以自己定义一个拒绝的策略,当新任务被拒绝之后,就会使用hander方法进行处理。

在java中也提供了Executors工具类,在这个工具类中提供了多个创建线程池的静态方法,其中包含newCachedThreadPool、newFixedThreadPool、newScheduledThreadPool、newSingleThreadExecutor等。但是他们每个方法都是创建了ThreadPoolExecutor对象,不同的是,每个对象的初始 参数值不一样;

java线程池中的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java线程池中核心线程会被回收吗、java线程池中的信息别忘了在本站进行查找喔。