下面这段代码的线程会执行吗?
ExecutorService es =
new ThreadPoolExecutor(0, 100000, 100000, TimeUnit.HOURS,new LinkedBlockingQueue<>());
答案是会。
但是为啥?
通过线程池的 execute 方法可以看到:
接着思考:
有没有进入队列?
先进入队列还是先创建线程?
都调用了队列的什么方法?
看最终代码:
public static void main(String[] args) {
class MyQueue implements InvocationHandler {
private BlockingQueue<?> queue = null;
public MyQueue(BlockingQueue<?> queue){
this.queue = queue;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName() + "::::::::::::::::::::::::::" + Arrays.toString(args));
return method.invoke(queue,args);
}
}
LinkedBlockingQueue queue = new LinkedBlockingQueue<Runnable>();
BlockingQueue queue2 = (BlockingQueue)Proxy.newProxyInstance(Test.class.getClassLoader(),new Class[]{BlockingQueue.class},new MyQueue(queue));
ExecutorService es = new ThreadPoolExecutor(1, 1, 100000, TimeUnit.HOURS, queue2, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
System.out.println("--------------------- new Thread ------------------------");
return new Thread(r);
}
});
es.execute(new Runnable() {
@Override
public void run() {
System.out.println("hello : " + Thread.currentThread().getId());
try {
Thread.sleep( 1 * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "------------ test obj -------------";
}
});
es.execute(new Runnable() {
@Override
public void run() {
System.out.println("hello : " + Thread.currentThread().getId());
try {
Thread.sleep( 1 * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "------------ test obj -------------";
}
});
}
变换ThreadPoolExecutor对象的第一个参数核心线程数:
核心线程数是0:
先走队列后走线程,执行的是队列的offer与poll
核心线程数大于0:
注意实际线程要大于核心线程数!
先走线程在走offer与take
核心线程数大于0:
注意实际线程要小于等于核心线程数!
先走线程,并且只走take
如果切换队列对象呢?
public static void main(String[] args) {
class MyQueue implements InvocationHandler {
private BlockingQueue<?> queue = null;
public MyQueue(BlockingQueue<?> queue){
this.queue = queue;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName() + "::::::::::::::::::::::::::" + Arrays.toString(args) + "\t" + Thread.currentThread().getId());
return method.invoke(queue,args);
}
}
BlockingQueue queue = new SynchronousQueue();
BlockingQueue queue2 = (BlockingQueue)Proxy.newProxyInstance(Test.class.getClassLoader(),new Class[]{BlockingQueue.class},new MyQueue(queue));
ExecutorService es = new ThreadPoolExecutor(1, 5, 2, TimeUnit.HOURS, queue2, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
System.out.println("--------------------- new Thread ------------------------");
return new Thread(r);
}
});
es.execute(new Runnable() {
@Override
public void run() {
System.out.println("hello : " + Thread.currentThread().getId());
try {
Thread.sleep( 1 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "------------ test obj -------------";
}
});
es.execute(new Runnable() {
@Override
public void run() {
System.out.println("hello : " + Thread.currentThread().getId());
try {
Thread.sleep( 1 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "------------ test obj -------------";
}
});
es.execute(new Runnable() {
@Override
public void run() {
System.out.println("hello : " + Thread.currentThread().getId());
try {
Thread.sleep( 1 * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "------------ test obj -------------";
}
});
}
再次尝试,注意观察线程ID
最终的出来的结论是:
1、当核心线程数为0的时候,会创建一个非核心线程进行执行
2、核心线程数不为0的时候,如果核心线程数在执行,会有一个非核心线程数从队列中取对象执行线程
3、核心线程数执行的是队列的take,非核心线程数执行队列的offer和poll
4、核心线程数不为0且队列为SynchronousQueue时,就成了单线程运行了