java并发编程实践笔记
类锁,对象锁,方法锁
先说结论:
synchronized修饰静态方法用的是类锁,等同于synchronized(xxx.class),synchronized修饰的是对象(无论是否静态)都是对象锁,synchronized修饰非静态方法的是方法锁–也属于对象锁—注意,修饰非静态方法时,等同于synchronized(this),锁的对象就是自身。
验证方法:
mapHolder
package ThreadDemo;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantLock;
public class MapHolder {
private Object myLock=new Object();
private Object myLock2=new Object();
private static Object static_lock1=new Object();
private static Object static_lock2=new Object();
private HashMap<String,String> map=new HashMap<>(10);
public synchronized static void static_put(){
// synchronized (static_lock1)
{
System.out.println(Thread.currentThread().getName()+"==== class lock begin :");
try {
Thread.sleep(1200);
}
catch (Exception ed){
ed.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"==== class lock end");
}
}
public static void static_remove(){
synchronized (MapHolder.class)
{
System.out.println(Thread.currentThread().getName()+"==== class lock begin - remove:");
try {
}
catch (Exception ed){
ed.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"==== class lock end - remove ");
}
}
public synchronized void put(String key,String value){
// synchronized (myLock)
{
System.out.println(Thread.currentThread().getName()+"====put begin:");
try {
Thread.sleep(1000);
}
catch (Exception ed){
ed.printStackTrace();
}
map.put(key,value);
System.out.println(Thread.currentThread().getName()+"====put end");
}
}
public void remove(String key){
synchronized (this)
{
if(map.containsKey(key)){
map.remove(key);
}
else{
try {
System.out.print(Thread.currentThread().getName());
System.out.println(" error : key not exist:" + key);
}
catch (Exception ed){
ed.printStackTrace();
}
}
}
}
}
t4
package ThreadDemo;
public class t4 {
public static void main(String[] args) throws Exception {
MapHolder objTmp=new MapHolder();
Runnable myThread02=new Runnable() {
@Override
public void run() {
objTmp.put("tf","gdgdgdg");
//objTmp.remove("tf");
}
};
Runnable myThread03=new Runnable() {
@Override
public void run() {
// objTmp.put("tf","gdgdgdg");
objTmp.remove("tf");
//objTmp.remove("tf");
}
};
Runnable sThread1=new Runnable() {
@Override
public void run() {
objTmp.static_put();
//objTmp.remove("tf");
}
};
Runnable sThread2=new Runnable() {
@Override
public void run() {
objTmp.static_remove();
}
};
// Thread t1 = new Thread(myThread01,"thread01");
// Thread t2 = new Thread(myThread01,"thread02");
// Thread t3 = new Thread(myThread01,"thread03");
// 实现多条线程顺序执行
// 默认情况下,依次调用线程的start()方法,线程执行的顺序随机
// t1.start();
// t2.start();
// t3.start();
Thread tmpT=null;
tmpT=new Thread(myThread02,"thread-first");
tmpT.start();
// tmpT=new Thread(myThread03,"thread02");
// tmpT.start();
for(int i=0;i< 10;i++){
tmpT=new Thread(myThread03,"thread"+i);
// tmpT=new Thread(new MyThread02(),"thread"+i);
tmpT.start();
}
tmpT=new Thread(sThread1,"static-thread-first");
tmpT.start();
tmpT=new Thread(sThread2,"static-thread-02");
tmpT.start();
/*
// 方法一:使用join()方法来阻塞主线程,线程得以顺序执行
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
// 方法二:
t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread:thread01");
}
},"thread01");
t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread:thread02");
}
},"thread02");
t3 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread:thread03");
}
},"thread03");
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(t1);
executorService.submit(t2);
executorService.submit(t3);
executorService.shutdown();
System.out.println("main ......");
*/
}
}
结果:
提醒:一个对象锁只允许一个线程持有,假如对象锁持有的线程可重复申请对象锁,则为可重入锁。
CountDownLatch例子
package ThreadDemo;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicInteger;
public class CountDownLatchDemo {
private static CountDownLatch latch=new CountDownLatch(20);
private static AtomicInteger count=new AtomicInteger(0);
public static void main(String[] args){
Runnable run1=new Runnable() {
@Override
public synchronized void run() {
try{
System.out.println(Thread.currentThread().getName()+":"+"任务 runnable 1 执行");
Thread.sleep(200);
System.out.println(Thread.currentThread().getName()+":"+"任务 runnable 1 执行(sleep)");
latch.countDown();
}
catch (Exception ed){
ed.printStackTrace();
}
}
};
Runnable run2=new Runnable() {
@Override
public synchronized void run() {
try{
System.out.println(Thread.currentThread().getName()+":"+"任务 runnable 2 执行");
Thread.sleep(300);
System.out.println(Thread.currentThread().getName()+":"+"任务 runnable 2 执行(sleep)");
latch.countDown();
}
catch (Exception ed){
ed.printStackTrace();
}
}
};
Runnable mainRun=new Runnable() {
@Override
public synchronized void run() {
try{
latch.await();
System.out.println("子线程终于都运行完毕了,主线程开始:"+Thread.currentThread().getName());
}
catch (Exception ed){
ed.printStackTrace();
}
}
};
for(int i=0;i<12;i++){
new Thread(run1,"run1+thread:"+i).start();
}
new Thread(mainRun,"main-app").start();
for(int i=0;i<12;i++){
new Thread(run2,"run2+thread:"+i).start();
}
}
}
执行结果:
run1+thread:0:任务 runnable 1 执行
run2+thread:0:任务 runnable 2 执行
run1+thread:0:任务 runnable 1 执行(sleep)
run1+thread:11:任务 runnable 1 执行
run2+thread:0:任务 runnable 2 执行(sleep)
run2+thread:11:任务 runnable 2 执行
run1+thread:11:任务 runnable 1 执行(sleep)
run1+thread:10:任务 runnable 1 执行
run2+thread:11:任务 runnable 2 执行(sleep)
run2+thread:10:任务 runnable 2 执行
run1+thread:10:任务 runnable 1 执行(sleep)
run1+thread:9:任务 runnable 1 执行
run1+thread:9:任务 runnable 1 执行(sleep)
run1+thread:8:任务 runnable 1 执行
run2+thread:10:任务 runnable 2 执行(sleep)
run2+thread:9:任务 runnable 2 执行
run1+thread:8:任务 runnable 1 执行(sleep)
run1+thread:7:任务 runnable 1 执行
run2+thread:9:任务 runnable 2 执行(sleep)
run2+thread:8:任务 runnable 2 执行
run1+thread:7:任务 runnable 1 执行(sleep)
run1+thread:6:任务 runnable 1 执行
run1+thread:6:任务 runnable 1 执行(sleep)
run1+thread:5:任务 runnable 1 执行
run2+thread:8:任务 runnable 2 执行(sleep)
run2+thread:7:任务 runnable 2 执行
run1+thread:5:任务 runnable 1 执行(sleep)
run1+thread:4:任务 runnable 1 执行
run2+thread:7:任务 runnable 2 执行(sleep)
run2+thread:6:任务 runnable 2 执行
run1+thread:4:任务 runnable 1 执行(sleep)
run1+thread:3:任务 runnable 1 执行
run1+thread:3:任务 runnable 1 执行(sleep)
run1+thread:2:任务 runnable 1 执行
run2+thread:6:任务 runnable 2 执行(sleep)
run2+thread:5:任务 runnable 2 执行
run1+thread:2:任务 runnable 1 执行(sleep)
run1+thread:1:任务 runnable 1 执行
run2+thread:5:任务 runnable 2 执行(sleep)
run2+thread:4:任务 runnable 2 执行
run1+thread:1:任务 runnable 1 执行(sleep)
子线程终于都运行完毕了,主线程开始:main-app
run2+thread:4:任务 runnable 2 执行(sleep)
run2+thread:3:任务 runnable 2 执行
run2+thread:3:任务 runnable 2 执行(sleep)
run2+thread:2:任务 runnable 2 执行
run2+thread:2:任务 runnable 2 执行(sleep)
run2+thread:1:任务 runnable 2 执行
run2+thread:1:任务 runnable 2 执行(sleep)
Process finished with exit code 0
FutureTask
package ThreadDemo.FutureTaskDemo;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
public class Demo1 {
public static void main(String[] args) throws Exception {
FutureTask<String> task=new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
TimeUnit.SECONDS.sleep(5);
System.out.println("运行完毕");
String str=new Date().toString();
return str;
}
});
new Thread(task,"ftask1").start();
System.out.println("执行futureTask:"+new Date());
String str=task.get();
System.out.println("返回结果值:"+str);
}
}
执行结果:
执行futureTask:Wed Oct 17 16:11:54 CST 2018
运行完毕
返回结果值:Wed Oct 17 16:11:59 CST 2018
信号量
package ThreadDemo;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class SemaphoreDemo {
private static Semaphore smp=new Semaphore(20);
private static Random rnd=new Random();
static class DemoClass implements Runnable{
private String id;
public DemoClass(String id){
this.id=id;
}
public synchronized void run(){
try{
smp.acquire();
System.out.println("Thread " + id + " is working");
//System.out.println("在等待的线程数目:"+ smp.getQueueLength());
work();
System.out.println("Thread " + id + " is over");
System.out.println("剩余许可证:"+smp.availablePermits());
}
catch (Exception ed){
}
finally {
smp.release();
}
}
private void work(){
int worktime = rnd.nextInt(1000);
try {
Thread.sleep(worktime);
}
catch (Exception ed){
}
finally {
}
}
}
public static void main(String[] args) throws Exception {
ExecutorService se= Executors.newCachedThreadPool();
for(int i=0;i< 100;i++){
se.submit(new DemoClass("Thread--"+i));
}
se.shutdown();
}
}
结果:
Thread Thread--0 is working
Thread Thread--1 is working
Thread Thread--2 is working
Thread Thread--3 is working
Thread Thread--4 is working
Thread Thread--5 is working
Thread Thread--6 is working
Thread Thread--7 is working
Thread Thread--8 is working
Thread Thread--9 is working
Thread Thread--10 is working
Thread Thread--11 is working
Thread Thread--12 is working
Thread Thread--13 is working
Thread Thread--14 is working
Thread Thread--15 is working
Thread Thread--16 is working
Thread Thread--17 is working
Thread Thread--18 is working
Thread Thread--19 is working
Thread Thread--12 is over
剩余许可证:0
Thread Thread--20 is working
Thread Thread--1 is over
剩余许可证:0
Thread Thread--21 is working
Thread Thread--21 is over
剩余许可证:0
Thread Thread--22 is working
Thread Thread--2 is over
剩余许可证:0
Thread Thread--23 is working
Thread Thread--5 is over
剩余许可证:0
Thread Thread--24 is working
Thread Thread--14 is over
剩余许可证:0
Thread Thread--25 is working
Thread Thread--15 is over
剩余许可证:0
Thread Thread--26 is working
Thread Thread--4 is over
剩余许可证:0
Thread Thread--27 is working
Thread Thread--17 is over
剩余许可证:0
Thread Thread--28 is working
Thread Thread--3 is over
剩余许可证:0
Thread Thread--29 is working
Thread Thread--9 is over
剩余许可证:0
Thread Thread--30 is working
Thread Thread--13 is over
剩余许可证:0
Thread Thread--31 is working
Thread Thread--19 is over
剩余许可证:0
Thread Thread--32 is working
Thread Thread--8 is over
剩余许可证:0
Thread Thread--33 is working
Thread Thread--26 is over
剩余许可证:0
Thread Thread--34 is working
Thread Thread--22 is over
剩余许可证:0
Thread Thread--35 is working
Thread Thread--16 is over
剩余许可证:0
Thread Thread--36 is working
Thread Thread--20 is over
剩余许可证:0
Thread Thread--37 is working
Thread Thread--30 is over
剩余许可证:0
Thread Thread--38 is working
Thread Thread--0 is over
剩余许可证:0
Thread Thread--39 is working
Thread Thread--10 is over
剩余许可证:0
Thread Thread--40 is working
Thread Thread--33 is over
剩余许可证:0
Thread Thread--41 is working
Thread Thread--6 is over
剩余许可证:0
Thread Thread--42 is working
Thread Thread--7 is over
剩余许可证:0
Thread Thread--43 is working
Thread Thread--31 is over
剩余许可证:0
Thread Thread--44 is working
Thread Thread--23 is over
剩余许可证:0
Thread Thread--45 is working
Thread Thread--24 is over
剩余许可证:0
Thread Thread--46 is working
Thread Thread--11 is over
剩余许可证:0
Thread Thread--47 is working
Thread Thread--18 is over
剩余许可证:0
Thread Thread--48 is working
Thread Thread--25 is over
剩余许可证:0
Thread Thread--49 is working
Thread Thread--47 is over
剩余许可证:0
Thread Thread--50 is working
Thread Thread--43 is over
剩余许可证:0
Thread Thread--51 is working
Thread Thread--32 is over
剩余许可证:0
Thread Thread--52 is working
Thread Thread--42 is over
剩余许可证:0
Thread Thread--53 is working
Thread Thread--50 is over
剩余许可证:0
Thread Thread--54 is working
Thread Thread--37 is over
剩余许可证:0
Thread Thread--55 is working
Thread Thread--38 is over
剩余许可证:0
Thread Thread--56 is working
Thread Thread--44 is over
剩余许可证:0
Thread Thread--57 is working
Thread Thread--29 is over
剩余许可证:0
Thread Thread--58 is working
Thread Thread--45 is over
剩余许可证:0
Thread Thread--59 is working
Thread Thread--54 is over
剩余许可证:0
Thread Thread--60 is working
Thread Thread--52 is over
剩余许可证:0
Thread Thread--61 is working
Thread Thread--27 is over
剩余许可证:0
Thread Thread--62 is working
Thread Thread--46 is over
剩余许可证:0
Thread Thread--63 is working
Thread Thread--53 is over
剩余许可证:0
Thread Thread--64 is working
Thread Thread--28 is over
剩余许可证:0
Thread Thread--65 is working
Thread Thread--56 is over
剩余许可证:0
Thread Thread--66 is working
Thread Thread--36 is over
剩余许可证:0
Thread Thread--67 is working
Thread Thread--35 is over
剩余许可证:0
Thread Thread--68 is working
Thread Thread--64 is over
剩余许可证:0
Thread Thread--69 is working
Thread Thread--39 is over
剩余许可证:0
Thread Thread--70 is working
Thread Thread--63 is over
剩余许可证:0
Thread Thread--71 is working
Thread Thread--48 is over
剩余许可证:0
Thread Thread--72 is working
Thread Thread--34 is over
剩余许可证:0
Thread Thread--73 is working
Thread Thread--41 is over
剩余许可证:0
Thread Thread--74 is working
Thread Thread--61 is over
剩余许可证:0
Thread Thread--75 is working
Thread Thread--75 is over
剩余许可证:0
Thread Thread--76 is working
Thread Thread--51 is over
剩余许可证:0
Thread Thread--77 is working
Thread Thread--72 is over
剩余许可证:0
Thread Thread--78 is working
Thread Thread--40 is over
剩余许可证:0
Thread Thread--79 is working
Thread Thread--59 is over
剩余许可证:0
Thread Thread--80 is working
Thread Thread--55 is over
剩余许可证:0
Thread Thread--81 is working
Thread Thread--77 is over
剩余许可证:0
Thread Thread--82 is working
Thread Thread--69 is over
剩余许可证:0
Thread Thread--83 is working
Thread Thread--58 is over
剩余许可证:0
Thread Thread--84 is working
Thread Thread--49 is over
剩余许可证:0
Thread Thread--85 is working
Thread Thread--78 is over
剩余许可证:0
Thread Thread--86 is working
Thread Thread--74 is over
剩余许可证:0
Thread Thread--87 is working
Thread Thread--66 is over
剩余许可证:0
Thread Thread--88 is working
Thread Thread--84 is over
剩余许可证:0
Thread Thread--89 is working
Thread Thread--68 is over
剩余许可证:0
Thread Thread--90 is working
Thread Thread--81 is over
剩余许可证:0
Thread Thread--91 is working
Thread Thread--60 is over
剩余许可证:0
Thread Thread--92 is working
Thread Thread--87 is over
剩余许可证:0
Thread Thread--93 is working
Thread Thread--82 is over
剩余许可证:0
Thread Thread--94 is working
Thread Thread--83 is over
剩余许可证:0
Thread Thread--95 is working
Thread Thread--71 is over
剩余许可证:0
Thread Thread--96 is working
Thread Thread--85 is over
剩余许可证:0
Thread Thread--97 is working
Thread Thread--62 is over
剩余许可证:0
Thread Thread--99 is working
Thread Thread--70 is over
剩余许可证:0
Thread Thread--98 is working
Thread Thread--89 is over
剩余许可证:0
Thread Thread--90 is over
剩余许可证:1
Thread Thread--76 is over
剩余许可证:2
Thread Thread--65 is over
剩余许可证:3
Thread Thread--91 is over
剩余许可证:4
Thread Thread--86 is over
剩余许可证:5
Thread Thread--57 is over
剩余许可证:6
Thread Thread--67 is over
剩余许可证:7
Thread Thread--79 is over
剩余许可证:8
Thread Thread--80 is over
剩余许可证:9
Thread Thread--73 is over
剩余许可证:10
Thread Thread--88 is over
剩余许可证:11
Thread Thread--99 is over
剩余许可证:12
Thread Thread--96 is over
剩余许可证:13
Thread Thread--94 is over
剩余许可证:14
Thread Thread--93 is over
剩余许可证:15
Thread Thread--97 is over
剩余许可证:16
Thread Thread--92 is over
剩余许可证:17
Thread Thread--95 is over
剩余许可证:18
Thread Thread--98 is over
剩余许可证:19
CyclicBarrier
package ThreadDemo.CyclicBarrierDemo;
import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DemoApp {
public static final int Count=10;
static CyclicBarrier barrier=new CyclicBarrier(Count, new Runnable() {
@Override
public void run() {
System.out.println(Count+"匹马已经就位,开始比赛了。。。。");
}
});
static ExecutorService service= Executors.newFixedThreadPool(Count+10);
public static class Horse implements Runnable{
private CyclicBarrier barrier;
private Random rnd=new Random();
private String name;
public Horse(CyclicBarrier barrier,String horseName){
this.barrier=barrier;
this.name=horseName;
}
public void run(){
try {
prepare();
barrier.await();
beginGame();
}
catch (Exception ed){
}
}
public synchronized void prepare(){
int worktime = rnd.nextInt(500);
try {
System.out.println(name+"正出发往起跑线赶去。");
Thread.sleep(worktime);
System.out.println(name+"经过了"+worktime+"毫秒终于赶到起跑线了");
}
catch (Exception ed){
}
finally {
}
}
public synchronized void beginGame(){
int worktime = rnd.nextInt(100);
try {
Thread.sleep(worktime);
System.out.println(name+"经过"+worktime+"毫秒终于到了终点了。");
}
catch (Exception ed){
}
finally {
}
}
}
public static void main(String[] args) throws Exception {
for(int i=0;i<50;i++){
new Thread(new Horse(barrier,"horse["+i+"]")).start();
}
}
}
horse[1]正出发往起跑线赶去。
horse[0]正出发往起跑线赶去。
horse[2]正出发往起跑线赶去。
horse[3]正出发往起跑线赶去。
horse[4]正出发往起跑线赶去。
horse[5]正出发往起跑线赶去。
horse[6]正出发往起跑线赶去。
horse[7]正出发往起跑线赶去。
horse[8]正出发往起跑线赶去。
horse[9]正出发往起跑线赶去。
horse[10]正出发往起跑线赶去。
horse[11]正出发往起跑线赶去。
horse[12]正出发往起跑线赶去。
horse[13]正出发往起跑线赶去。
horse[14]正出发往起跑线赶去。
horse[15]正出发往起跑线赶去。
horse[16]正出发往起跑线赶去。
horse[17]正出发往起跑线赶去。
horse[18]正出发往起跑线赶去。
horse[19]正出发往起跑线赶去。
horse[20]正出发往起跑线赶去。
horse[21]正出发往起跑线赶去。
horse[22]正出发往起跑线赶去。
horse[23]正出发往起跑线赶去。
horse[25]正出发往起跑线赶去。
horse[24]正出发往起跑线赶去。
horse[26]正出发往起跑线赶去。
horse[27]正出发往起跑线赶去。
horse[28]正出发往起跑线赶去。
horse[29]正出发往起跑线赶去。
horse[30]正出发往起跑线赶去。
horse[31]正出发往起跑线赶去。
horse[32]正出发往起跑线赶去。
horse[33]正出发往起跑线赶去。
horse[34]正出发往起跑线赶去。
horse[35]正出发往起跑线赶去。
horse[36]正出发往起跑线赶去。
horse[37]正出发往起跑线赶去。
horse[38]正出发往起跑线赶去。
horse[39]正出发往起跑线赶去。
horse[40]正出发往起跑线赶去。
horse[41]正出发往起跑线赶去。
horse[42]正出发往起跑线赶去。
horse[43]正出发往起跑线赶去。
horse[44]正出发往起跑线赶去。
horse[48]正出发往起跑线赶去。
horse[49]正出发往起跑线赶去。
horse[47]正出发往起跑线赶去。
horse[46]正出发往起跑线赶去。
horse[45]正出发往起跑线赶去。
horse[10]经过了8毫秒终于赶到起跑线了
horse[1]经过了16毫秒终于赶到起跑线了
horse[42]经过了18毫秒终于赶到起跑线了
horse[31]经过了31毫秒终于赶到起跑线了
horse[27]经过了33毫秒终于赶到起跑线了
horse[49]经过了47毫秒终于赶到起跑线了
horse[5]经过了76毫秒终于赶到起跑线了
horse[18]经过了78毫秒终于赶到起跑线了
horse[40]经过了87毫秒终于赶到起跑线了
horse[46]经过了107毫秒终于赶到起跑线了
10匹马已经就位,开始比赛了。。。。
horse[46]经过1毫秒终于到了终点了。
horse[27]经过2毫秒终于到了终点了。
horse[18]经过5毫秒终于到了终点了。
horse[42]经过7毫秒终于到了终点了。
horse[49]经过10毫秒终于到了终点了。
horse[6]经过了122毫秒终于赶到起跑线了
horse[10]经过17毫秒终于到了终点了。
horse[23]经过了128毫秒终于赶到起跑线了
horse[47]经过了129毫秒终于赶到起跑线了
horse[5]经过23毫秒终于到了终点了。
horse[35]经过了140毫秒终于赶到起跑线了
horse[4]经过了145毫秒终于赶到起跑线了
horse[1]经过38毫秒终于到了终点了。
horse[31]经过44毫秒终于到了终点了。
horse[32]经过了158毫秒终于赶到起跑线了
horse[14]经过了159毫秒终于赶到起跑线了
horse[44]经过了158毫秒终于赶到起跑线了
horse[24]经过了169毫秒终于赶到起跑线了
horse[20]经过了182毫秒终于赶到起跑线了
10匹马已经就位,开始比赛了。。。。
horse[45]经过了183毫秒终于赶到起跑线了
horse[44]经过5毫秒终于到了终点了。
horse[32]经过5毫秒终于到了终点了。
horse[4]经过10毫秒终于到了终点了。
horse[40]经过93毫秒终于到了终点了。
horse[35]经过21毫秒终于到了终点了。
horse[11]经过了208毫秒终于赶到起跑线了
horse[0]经过了212毫秒终于赶到起跑线了
horse[24]经过32毫秒终于到了终点了。
horse[43]经过了218毫秒终于赶到起跑线了
horse[6]经过37毫秒终于到了终点了。
horse[8]经过了232毫秒终于赶到起跑线了
horse[47]经过50毫秒终于到了终点了。
horse[29]经过了243毫秒终于赶到起跑线了
horse[14]经过62毫秒终于到了终点了。
horse[3]经过了253毫秒终于赶到起跑线了
horse[20]经过70毫秒终于到了终点了。
horse[36]经过了256毫秒终于赶到起跑线了
horse[23]经过76毫秒终于到了终点了。
horse[30]经过了261毫秒终于赶到起跑线了
horse[12]经过了267毫秒终于赶到起跑线了
10匹马已经就位,开始比赛了。。。。
horse[12]经过4毫秒终于到了终点了。
horse[36]经过14毫秒终于到了终点了。
horse[30]经过15毫秒终于到了终点了。
horse[8]经过15毫秒终于到了终点了。
horse[25]经过了287毫秒终于赶到起跑线了
horse[28]经过了289毫秒终于赶到起跑线了
horse[19]经过了295毫秒终于赶到起跑线了
horse[43]经过28毫秒终于到了终点了。
horse[38]经过了301毫秒终于赶到起跑线了
horse[26]经过了304毫秒终于赶到起跑线了
horse[48]经过了303毫秒终于赶到起跑线了
horse[33]经过了311毫秒终于赶到起跑线了
horse[11]经过52毫秒终于到了终点了。
horse[15]经过了320毫秒终于赶到起跑线了
horse[16]经过了334毫秒终于赶到起跑线了
horse[45]经过67毫秒终于到了终点了。
horse[29]经过69毫秒终于到了终点了。
horse[9]经过了340毫秒终于赶到起跑线了
10匹马已经就位,开始比赛了。。。。
horse[25]经过6毫秒终于到了终点了。
horse[38]经过9毫秒终于到了终点了。
horse[37]经过了353毫秒终于赶到起跑线了
horse[48]经过15毫秒终于到了终点了。
horse[3]经过90毫秒终于到了终点了。
horse[39]经过了360毫秒终于赶到起跑线了
horse[0]经过97毫秒终于到了终点了。
horse[13]经过了367毫秒终于赶到起跑线了
horse[19]经过27毫秒终于到了终点了。
horse[28]经过31毫秒终于到了终点了。
horse[17]经过了377毫秒终于赶到起跑线了
horse[7]经过了381毫秒终于赶到起跑线了
horse[15]经过47毫秒终于到了终点了。
horse[9]经过54毫秒终于到了终点了。
horse[16]经过57毫秒终于到了终点了。
horse[33]经过75毫秒终于到了终点了。
horse[26]经过75毫秒终于到了终点了。
horse[34]经过了438毫秒终于赶到起跑线了
horse[41]经过了460毫秒终于赶到起跑线了
horse[22]经过了466毫秒终于赶到起跑线了
horse[2]经过了473毫秒终于赶到起跑线了
horse[21]经过了491毫秒终于赶到起跑线了
10匹马已经就位,开始比赛了。。。。
horse[37]经过15毫秒终于到了终点了。
horse[17]经过16毫秒终于到了终点了。
horse[39]经过33毫秒终于到了终点了。
horse[7]经过41毫秒终于到了终点了。
horse[21]经过46毫秒终于到了终点了。
horse[41]经过54毫秒终于到了终点了。
horse[2]经过59毫秒终于到了终点了。
horse[22]经过67毫秒终于到了终点了。
horse[34]经过70毫秒终于到了终点了。
horse[13]经过70毫秒终于到了终点了。
CompletionService和ExecutorCompletionService
传统上当需要进行并行计算然后汇总数据时候,可以这样计算:
package ThreadDemo.part2.CompletionTest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class TraditionalTest1 {
public static void main(String[] args){
AtomicInteger taskSize=new AtomicInteger(5);
ExecutorService executor= Executors.newFixedThreadPool(taskSize.get());
List<Future<Integer>> futureList=new ArrayList<>();
CountDownLatch countDownLatch=new CountDownLatch(5);
for(int i=1;i<=5;i++){
int sleep=5-i;
final int value= i;
Future<Integer> futureTask=executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println("========thread "+value+" begin:");
TimeUnit.SECONDS.sleep(sleep);
System.out.println("========thread "+value+" end.");
countDownLatch.countDown();
return value;
}
});
futureList.add(futureTask);
}
executor.submit(new Runnable() {
@Override
public void run() {
try {
countDownLatch.await();
System.out.println("===========================好了,现在来汇总进行计算。");
int tmpTotal=0;
synchronized (this){
for(Future<Integer> task: futureList){
int tmp=task.get();
System.out.println(tmp);
tmpTotal+=tmp;
}
}
System.out.println("计算结果为:"+tmpTotal);
}
catch (Exception ed){
ed.printStackTrace();
}
}
});
System.out.println("====+++++++++========");
executor.shutdown();
}
}
结果为:
====+++++++++========
========thread 1 begin:
========thread 2 begin:
========thread 3 begin:
========thread 5 begin:
========thread 5 end.
========thread 4 begin:
========thread 4 end.
========thread 3 end.
========thread 2 end.
========thread 1 end.
===========================好了,现在来汇总进行计算。
1
2
3
4
5
计算结果为:15
当然,现在可以用completionService来计算:
package ThreadDemo.part2.CompletionTest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class CompletionServiceTest {
public static void main(String[] args){
ExecutorService executor= Executors.newFixedThreadPool(5);
CompletionService<Integer> completionService=new ExecutorCompletionService<>(executor);
for(int i=1;i<=5;i++){
int sleep=5-i;
final int value= i;
completionService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println("========thread "+value+" begin:");
TimeUnit.SECONDS.sleep(sleep);
System.out.println("========thread "+value+" end.");
return value;
}
});
}
System.out.println("===========================好了,现在来汇总进行计算。");
int tmpTotal=0;
for(int i=1;i<=5;i++){
try {
Integer tmp = completionService.take().get();
System.out.println(tmp);
tmpTotal+=tmp;
}
catch (Exception ed){
ed.printStackTrace();
}
}
System.out.println("计算结果为:"+tmpTotal);
executor.shutdown();
}
}
结果为:
===========================好了,现在来汇总进行计算。
========thread 1 begin:
========thread 2 begin:
========thread 3 begin:
========thread 4 begin:
========thread 5 begin:
========thread 5 end.
5
========thread 4 end.
4
========thread 3 end.
3
========thread 2 end.
2
========thread 1 end.
1
计算结果为:15