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 ......");
        */

    }
}

结果:

java并发编程实践笔记

提醒:一个对象锁只允许一个线程持有,假如对象锁持有的线程可重复申请对象锁,则为可重入锁。

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