@Test
public void test1() {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
以上是我在别的博客找到的例子,但是这个例子无法实现“每2秒打印3个数字”这个效果。前三个线程被执行,但是后面加入的都不行。for并没有被阻塞。
非main函数下,你的测试函数的主线程,不会等待线程池中的其他线程结束,就结束线程了!你改成主函数就正常了,改成被主函数调用也正常了。也可以在测试函数的for循环外增加等待时间,或者增加判断所以线程是否完全结束。
什么JDK版本?看代码应该是可以的。
我在for里面打印了一下线程池的状态
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 3, active threads = 3, queued tasks = 1, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 3, active threads = 3, queued tasks = 2, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 3, active threads = 3, queued tasks = 3, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 3, active threads = 3, queued tasks = 4, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 3, active threads = 3, queued tasks = 5, completed tasks = 0]
java.util.concurrent.ThreadPoolExecutor@5b37e0d2[Running, pool size = 3, active threads = 3, queued tasks = 6, completed tasks = 0]
在两秒钟所有的这个for循环都执行完了 三个以后的线程只能在队列中排队了 你打印时间长点会继续的
completed tasks = 0说明你的Runnable没有一个是执行完成的,检查一下你是不是开debug在public void run()里面打了断点导致所以线程block在run方法里面。
fix的线程池,线程数固定,可能达到后,后边的任务就被丢弃了
run 方法里需要加while true,要不然就是这个线程打印一次就退出了
你好,你的代码是可以正常运行的,至于你说同时打印3个数这个问题,我可以解析一下为什么没有达到你的预期,代码中创建的coreSize是3个线程的线程,不代表这3个线程一定会并发同时执行,线程的执行需要对CPU进行资源抢占,如果运行环境有3核的CPU,并且都能同时抢占到资源,是可以同时打印出3个数来的,但是如果运行环境是单核或者双核的,资源不一定能够同时抢占成功,这个时候就会出现调度,就是线程轮流使用CPU。
fix线程设置为3,就是说corePoolSize和MixPoolSize都是3,后来再来的任务如果当前没有空闲的线程就直接放到阻塞队列里。
等到有空闲的线程了再执行阻塞队列里的任务。所以是不会丢掉任务的。
各位抱歉啊,这些答案都不是很好的能解析我遇到的问题,我觉得问题是出在Thread.sleep(2000)这一句这里,因为所有线程都是没有complete的。Thread.sleep(2000)只是为了让当前线程睡眠,但是线程却又是运行中的,所以后续线程都在排队。只有当这三个线程都在输出数字后两秒才醒来,让后面的线程进来,然后后来的三个线程输出数字,睡两秒再醒来。所以才会有“每隔两秒就有三个数字输出”的效果。但是调用了sleep后所有的线程都睡了没醒,所以才会没有complete。如果Thread.sleep(2000)去掉,System.out.println(index);改为System.out.println(Math.pow(index, 64))这样让前三个线程处于运算状态而阻塞后面的线程,就会看到active threads,queued tasks,completed tasks都在改变,能看得出排队和完成的效果。至于Thread.sleep(2000)为什么会让这些线程睡死就暂时不得而知。
我的环境:
Windows 10 professional
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
解决问题了 换成主函数就成功了