线程池创建五个线程,每个线程往list中添加100个元素。synchronized只锁线程共享变量list对象,代码段内仅添加元素及打印信息。设置10ms睡眠时间给其余线程机会。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
//list是所有线程共享变量需要加锁避免冲突
final List list = new ArrayList();
for(int i=0;i<5;i++) {
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
//j是线程内部变量,每个线程都有一份,自己会管理,不会冲突
int j=100;
while(j>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (list) {
list.add(j);
System.out.println(Thread.currentThread().getName()+"---------"+list.size());
j--;
}
}
}
});
}
fixedThreadPool.shutdown();
//这里的sysout输出是在main线程中的,其list的size根据当时这个list的情况只输出一次,可能是任意小于500的值
System.out.println(Thread.currentThread().getName()+"---------"+list.size());
输出结果:(注意这里的main-----0 这个值是fixedThreadPool.shutdown();之后的sysout输出。)包括main线程一共有6个线程。
main线程不执行run内代码段,直接往下继续执行其余代码。
main---------0
pool-1-thread-2---------1
pool-1-thread-3---------2
pool-1-thread-4---------3....
pool-1-thread-3---------497
pool-1-thread-2---------498
pool-1-thread-4---------499
pool-1-thread-5---------500
关于main线程:main线程可能在其余子线程执行完就执行到尾了。但是很多生产情况是要获取子线程结果来处理的。此时可以设置等待时间等待子线程结束。
// 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。
threadPool.shutdown();
设置最长等待5秒
if(!pool.awaitTermination(5, TimeUnit.SECONDS)){
// 超时的时候向线程池中所有的线程发出中断(interrupted)。再超时直接强行关闭。
pool.shutdownNow();
}
或者可以用join()方法,保证子线程执行完才执行主线程(这个例子用简单的new Thread,threadPool可以自己延伸):
// 使用线程安全的Vector
Vector<Thread> threads = new Vector<Thread>();
for (int i = 0; i < 10; i++) { ....... 省略创建子线程方法
threads.add(iThread); // 将每一个子线程放到集合中,iThread代表某个子线程
}
for (Thread iThread : threads) { //在主线程中循环调用子线程的join()
try {
// 等待所有线程执行完毕
iThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
- System.out.println("主线执行。"); //这个sysout会在所有子线程完成后执行
关于shutdown:“问题解答完毕后请举手示意!”是shutdown方法。“老师我做完了!”是各个任务(Runnable)的运行结束。
shutdown只作为通知的作用
Vector和List :
....
// final List list = new ArrayList();
final Vector vec = new Vector();
....
// synchronized (vec) {
vec.add(j);
System.out.println(Thread.currentThread().getName()+"---------"+vec.size());
j--;
// }
....
输出:
pool-1-thread-3---------3
pool-1-thread-1---------4
pool-1-thread-2---------3....
pool-1-thread-1---------498
pool-1-thread-5---------499
pool-1-thread-4---------500
vector线程安全,list不安全。注调synchronized之后list添加元素个数少于500,vector安全添加500个元素。
但是由于add和sysout vector.size()没在一个锁里,所以,打印的元素个数是乱的 。
参考:https://blog.csdn.net/zaozi/article/details/38854561
https://blog.csdn.net/star890124/article/details/48243221