import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CurrentSync {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/**
* 首先说说线程池的创建-----以前都理解错误了
*
* 原理:线程池按以下行为执行任务 1.当线程数小于核心线程数时,创建线程。
2.当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
3.当线程数大于等于核心线程数,且任务队列已满,若线程数小于最大线程数,创建线程,若线程数等于最大线程数,抛出异常,拒绝任务
* 再来说说参数:
* 1.corePoolSize 核心线程数,核心线程会一直存活,即使没有任务需要处理。
* 当线程数小于核心线程数时,即使现有的线程空闲,线程池也会优先创建新线程来处理任务,而不是直接交给现有的线程处理。
* 核心线程在allowCoreThreadTimeout被设置为true时会超时退出,默认情况下不会退出。
*
* 2.maximumPoolSize 当线程数大于或等于核心线程,且任务队列已满时,线程池会创建新的线程,直到线程数量达到maxPoolSize。
* 如果线程数已等于maxPoolSize,且任务队列已满,则已超出线程池的处理能力,线程池会拒绝处理任务而抛出异常。(默认情况,具体见handler参数设置)
*
* 3.keepAliveTime 当线程空闲时间达到keepAliveTime,该线程会退出,直到线程数量等于corePoolSize。
* 如果allowCoreThreadTimeout设置为true,则所有线程均会退出直到线程数量为0。
*
* 4.unit 设置keepAliveTime的单位
*
* 5.workQueue 设置任务队列大小,不要设置成无限大,会导致任务响应时间过长
*
* 6.threadFactory 在创建ThreadPoolExecutor时还可以为其指定ThreadFactory, 当线程池需要创建新的线程时会调用ThreadFactory的newThread方法.
* 默认的ThreadFactory创建的线程是nonDaemon, 线程优先级为NORM_PRIORITY的线程, 并且为其指定了可识别的线程名称
*
* 7.handler 饱和策略 如果线程池使用的是有界队列, 那么当有界队列满时继续提交task时饱和策略会被触发.
* 如果线程池使用的是同步队列, 那么当线程池无法创建新的线程接手task时饱和策略会被触发.
* 如果线程池被关闭后, 仍然向其提交task时, 饱和策略也会被触发.
* ThreadPoolExecutor类中预定义了多个RejectedExecutionHandler的实现类: AbortPolicy, CallerRunsPolicy, DiscardPolicy, 和DiscardOldestPolicy.
* AbortPolicy 是默认的饱和策略,可见默认情况下, 触发饱和策略时将抛出RejectedExecutionException异常.
* CallerRunsPolicy 饱和时将在提交task的线程在MAIN中执行task, 而不是由线程池中的线程执行
* DiscardPolicy 该策略将最新提交的task丢弃:
* DiscardOldestPolicy. 该策略丢弃队列中处于对头的task, 且试着再次提交最新的task
*
* 一:关于corePoolSize的计算
* 每个任务需要tasktime秒处理,则每个线程每钞可处理1/tasktime个任务
* 系统每秒有tasks个任务需要处理,则需要的线程数为:tasks/(1/tasktime),即tasks*tasktime个线程数
*
* 二:关于queueCapacity队列长度的计算
* responsetime,系统允许任务最大的响应时间,队列长度可以设置为(corePoolSize/tasktime)*responsetime
*
* 结尾:扩展ThreadPoolExecutor
ThreadPoolExecutor类提供了多个"钩子"方法, 以供其子类实现, 比如beforeExecute, afterExecute, terminated等.
所谓"钩子"是指基类预留的, 但是没有提供具体实现的方法, 其方法体为空. 子类可以根据需要为"钩子"提供具体实现
*/
CountDownLatch latch=new CountDownLatch(1000);
ThreadPoolExecutor pool = new ThreadPoolExecutor(20, 60, 10L,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(940), new MyThreadFactory("first Factory"), new MyPolicyHandler());
// pool.allowCoreThreadTimeOut(true);
for (int i = 0; i < 1000; i++) {
pool.submit(new MyThread(i,latch));
}
// while(true){
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println("pool size: " + pool.getPoolSize());
// System.out.println("signal : "+latch.getCount());
// }
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ok jiesu");
}
}
</pre><pre code_snippet_id="1555420" snippet_file_name="blog_20160113_3_6118087" name="code" class="java"><pre name="code" class="java">import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MyThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String poolName;
private final String threadNme;
private final String DEFAULT_NAME = "MyThread";
private static final Logger log = Logger.getAnonymousLogger();
public MyThreadFactory(String poolName) {
this.poolName = poolName+"_"+poolNumber.getAndIncrement();
this.threadNme = DEFAULT_NAME+"_"+threadNumber.getAndIncrement();
}
public MyThreadFactory(String poolName, String threadNme) {
this.poolName = poolName+"_"+poolNumber.getAndIncrement();
this.threadNme = threadNme;
}
public Thread newThread(Runnable runnable) {
Thread t = new Thread(runnable, poolName+"--"+threadNme+"_"+threadNumber.getAndIncrement());
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
log.log(Level.SEVERE, "UNCAUGHT in thread " + t.getName(), e);
}
});
return t;
}
}
import java.util.concurrent.CountDownLatch;
public class MyThread implements Runnable {
int i;
CountDownLatch latch;
public MyThread(int i, CountDownLatch latch){
this.i = i;
this.latch = latch;
}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ok - "+i);
latch.countDown();
}
}
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class MyPolicyHandler implements RejectedExecutionHandler {
private CountDownLatch latch;
public MyPolicyHandler() {
}
public MyPolicyHandler(CountDownLatch latch) {
this.latch = latch;
}
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.out.println("Task " + r.toString() +
" rejected from " +
executor.toString());
}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class MyThreadPoolExecutor extends ThreadPoolExecutor {
public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
System.out.println("before");
System.out.println(t.getName());
System.out.println(r.toString());
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
System.out.println("after");
}
}
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class MyTest {
public static void main(String[] args) {
MyThreadPoolExecutor pool = new MyThreadPoolExecutor(4, 10, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(100));
for (int i = 0; i < 1; i++) {
pool.submit(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("t");
}
});
}
}
}