`

Java并发编程:CountDownLatch、CyclicBarrier、Semaphore、Phaser

 
阅读更多

 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法。

  以下是本文目录大纲:

  一.CountDownLatch用法

  二.CyclicBarrier用法

  三.Semaphore用法

      四.Phaser

  若有不正之处请多多谅解,并欢迎批评指正。

  请尊重作者劳动成果,转载请标明原文链接:

  http://www.cnblogs.com/dolphin0520/p/3920397.html

  

一.CountDownLatch用法

  CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。

  CountDownLatch类只提供了一个构造器:

1
public CountDownLatch(int count) {  };  //参数count为计数值

   然后下面这3个方法是CountDownLatch类中最重要的方法:

1
2
3
public void await() throws InterruptedException { };   //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public void countDown() { };  //将count值减1

   下面看一个例子大家就清楚CountDownLatch的用法了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class Test {
     public static void main(String[] args) {   
         final CountDownLatch latch = new CountDownLatch(2);
          
         new Thread(){
             public void run() {
                 try {
                     System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
                    Thread.sleep(3000);
                    System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
                    latch.countDown();
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
             };
         }.start();
          
         new Thread(){
             public void run() {
                 try {
                     System.out.println("子线程"+Thread.currentThread().getName()+"正在执行");
                     Thread.sleep(3000);
                     System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕");
                     latch.countDown();
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
             };
         }.start();
          
         try {
             System.out.println("等待2个子线程执行完毕...");
            latch.await();
            System.out.println("2个子线程已经执行完毕");
            System.out.println("继续执行主线程");
        catch (InterruptedException e) {
            e.printStackTrace();
        }
     }
}

   执行结果:

 View Code

二.CyclicBarrier用法

  字面意思回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。我们暂且把这个状态就叫做barrier,当调用await()方法之后,线程就处于barrier了。

  CyclicBarrier类位于java.util.concurrent包下,CyclicBarrier提供2个构造器:

1
2
3
4
5
public CyclicBarrier(int parties, Runnable barrierAction) {
}
 
public CyclicBarrier(int parties) {
}

  参数parties指让多少个线程或者任务等待至barrier状态;参数barrierAction为当这些线程都达到barrier状态时会执行的内容。

  然后CyclicBarrier中最重要的方法就是await方法,它有2个重载版本:

1
2
public int await() throws InterruptedException, BrokenBarrierException { };
public int await(long timeout, TimeUnit unit)throws InterruptedException,BrokenBarrierException,TimeoutException { };

   第一个版本比较常用,用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务;

  第二个版本是让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务。

  下面举几个例子就明白了:

  假若有若干个线程都要进行写数据操作,并且只有所有线程都完成写数据操作之后,这些线程才能继续做后面的事情,此时就可以利用CyclicBarrier了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Test {
    public static void main(String[] args) {
        int N = 4;
        CyclicBarrier barrier  = new CyclicBarrier(N);
        for(int i=0;i<N;i++)
            new Writer(barrier).start();
    }
    static class Writer extends Thread{
        private CyclicBarrier cyclicBarrier;
        public Writer(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
 
        @Override
        public void run() {
            System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");
            try {
                Thread.sleep(5000);      //以睡眠来模拟写入数据操作
                System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
                cyclicBarrier.await();
            catch (InterruptedException e) {
                e.printStackTrace();
            }catch(BrokenBarrierException e){
                e.printStackTrace();
            }
            System.out.println("所有线程写入完毕,继续处理其他任务...");
        }
    }
}

   执行结果:

 View Code

  从上面输出结果可以看出,每个写入线程执行完写数据操作之后,就在等待其他线程写入操作完毕。

  当所有线程线程写入操作完毕之后,所有线程就继续进行后续的操作了。

  如果说想在所有线程写入操作完之后,进行额外的其他操作可以为CyclicBarrier提供Runnable参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Test {
    public static void main(String[] args) {
        int N = 4;
        CyclicBarrier barrier  = new CyclicBarrier(N,new Runnable() {
            @Override
            public void run() {
                System.out.println("当前线程"+Thread.currentThread().getName());   
            }
        });
         
        for(int i=0;i<N;i++)
            new Writer(barrier).start();
    }
    static class Writer extends Thread{
        private CyclicBarrier cyclicBarrier;
        public Writer(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
 
        @Override
        public void run() {
            System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");
            try {
                Thread.sleep(5000);      //以睡眠来模拟写入数据操作
                System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
                cyclicBarrier.await();
            catch (InterruptedException e) {
                e.printStackTrace();
            }catch(BrokenBarrierException e){
                e.printStackTrace();
            }
            System.out.println("所有线程写入完毕,继续处理其他任务...");
        }
    }
}

   运行结果:

 View Code

  从结果可以看出,当四个线程都到达barrier状态后,会从四个线程中选择一个线程去执行Runnable。

   下面看一下为await指定时间的效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Test {
    public static void main(String[] args) {
        int N = 4;
        CyclicBarrier barrier  = new CyclicBarrier(N);
         
        for(int i=0;i<N;i++) {
            if(i<N-1)
                new Writer(barrier).start();
            else {
                try {
                    Thread.sleep(5000);
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
                new Writer(barrier).start();
            }
        }
    }
    static class Writer extends Thread{
        private CyclicBarrier cyclicBarrier;
        public Writer(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
 
        @Override
        public void run() {
            System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");
            try {
                Thread.sleep(5000);      //以睡眠来模拟写入数据操作
                System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
                try {
                    cyclicBarrier.await(2000, TimeUnit.MILLISECONDS);
                catch (TimeoutException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            catch (InterruptedException e) {
                e.printStackTrace();
            }catch(BrokenBarrierException e){
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"所有线程写入完毕,继续处理其他任务...");
        }
    }
}

   执行结果:

 View Code

  上面的代码在main方法的for循环中,故意让最后一个线程启动延迟,因为在前面三个线程都达到barrier之后,等待了指定的时间发现第四个线程还没有达到barrier,就抛出异常并继续执行后面的任务。

  另外CyclicBarrier是可以重用的,看下面这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class Test {
    public static void main(String[] args) {
        int N = 4;
        CyclicBarrier barrier  = new CyclicBarrier(N);
         
        for(int i=0;i<N;i++) {
            new Writer(barrier).start();
        }
         
        try {
            Thread.sleep(25000);
        catch (InterruptedException e) {
            e.printStackTrace();
        }
         
        System.out.println("CyclicBarrier重用");
         
        for(int i=0;i<N;i++) {
            new Writer(barrier).start();
        }
    }
    static class Writer extends Thread{
        private CyclicBarrier cyclicBarrier;
        public Writer(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
 
        @Override
        public void run() {
            System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据...");
            try {
                Thread.sleep(5000);      //以睡眠来模拟写入数据操作
                System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕");
             
                cyclicBarrier.await();
            catch (InterruptedException e) {
                e.printStackTrace();
            }catch(BrokenBarrierException e){
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"所有线程写入完毕,继续处理其他任务...");
        }
    }
}

   执行结果:

 View Code

  从执行结果可以看出,在初次的4个线程越过barrier状态后,又可以用来进行新一轮的使用。而CountDownLatch无法进行重复使用。

三.Semaphore用法

  Semaphore翻译成字面意思为 信号量,Semaphore可以控同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。

  Semaphore类位于java.util.concurrent包下,它提供了2个构造器:

1
2
3
4
5
6
public Semaphore(int permits) {          //参数permits表示许可数目,即同时可以允许多少线程进行访问
    sync = new NonfairSync(permits);
}
public Semaphore(int permits, boolean fair) {    //这个多了一个参数fair表示是否是公平的,即等待时间越久的越先获取许可
    sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
}

   下面说一下Semaphore类中比较重要的几个方法,首先是acquire()、release()方法:

1
2
3
4
public void acquire() throws InterruptedException {  }     //获取一个许可
public void acquire(int permits) throws InterruptedException { }    //获取permits个许可
public void release() { }          //释放一个许可
public void release(int permits) { }    //释放permits个许可

  acquire()用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可。

  release()用来释放许可。注意,在释放许可之前,必须先获获得许可。

  这4个方法都会被阻塞,如果想立即得到执行结果,可以使用下面几个方法:

1
2
3
4
public boolean tryAcquire() { };    //尝试获取一个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException { };  //尝试获取一个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false
public boolean tryAcquire(int permits) { }; //尝试获取permits个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException { }; //尝试获取permits个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false

   另外还可以通过availablePermits()方法得到可用的许可数目。

  下面通过一个例子来看一下Semaphore的具体使用:

  假若一个工厂有5台机器,但是有8个工人,一台机器同时只能被一个工人使用,只有使用完了,其他工人才能继续使用。那么我们就可以通过Semaphore来实现:

    执行结果:

 View Code

  

  下面对上面说的三个辅助类进行一个总结:

  1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:

    CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;

    而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;

    另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。

  2)Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。

 

四.Semaphore用法

从java7开始在concurrent包中加入了Phaser类,它几乎可以取代CountDownLatch和CyclicBarrier, 其功能更灵活,更强大,支持动态调整需要控制的线程数。下面以一个具体实例说明这个Phaser类的用处,相信理解这个例子后,其功能不言而喻

 

Sample 1

在有些场景下,我们希望控制多个线程的启动时机:例如在并发相关的单元测试中,有时需要控制线程的启动时机,以期获得最大程度的并发,通常我们会使用CountDownLatch,以下是使用Phaser的版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.util.concurrent.Phaser;
 
public class PhaserTest1 {
 
    public static void main(String args[]) {
        //
        final int count = 5;
        final Phaser phaser = new Phaser(count);
        for(int i = 0; i < count; i++) {
            System.out.println("starting thread, id: " + i);
            final Thread thread = new Thread(new Task(i, phaser));
            thread.start();
        }
    }
     
    public static class Task implements Runnable {
        //
        private final int id;
        private final Phaser phaser;
 
        public Task(int id, Phaser phaser) {
            this.id = id;
            this.phaser = phaser;
 
        }
         
        @Override
        public void run() {
            phaser.arriveAndAwaitAdvance();
            System.out.println("in Task.run(), phase: " + phaser.getPhase() + ", id: " this.id);
        }
    }
}

 

以上例子中,由于线程是在一个循环中start,因此start的时机有一定的间隔。本例中这些线程实际开始工作的时机是在所有的线程都调用了phaser.arriveAndAwaitAdvance()之后。

此外,如果留心arriveAndAwaitAdvance()方法的签名,会发现它并没有抛出InterruptedException,实际上,即使 当前线程被中断,arriveAndAwaitAdvance()方法也不会返回,而是继续等待。如果在等待时希望可中断,或者可超时,那么需要使用以下 方法:

1
2
3
awaitAdvance(arrive())  // 等效于arriveAndAwaitAdvance()
awaitAdvanceInterruptibly(int phase)
awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit)

 

3.2 Sample 2

有些时候我们希望只有在某些外部条件满足时,才真正开始任务的执行,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.Phaser;
 
public class PhaserTest2 {
 
    public static void main(String args[]) throws Exception {
        //
        final Phaser phaser = new Phaser(1);
        for(int i = 0; i < 5; i++) {
            phaser.register();
            System.out.println("starting thread, id: " + i);
            final Thread thread = new Thread(new Task(i, phaser));
            thread.start();
        }
         
        //
        System.out.println("Press ENTER to continue");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        reader.readLine();
        phaser.arriveAndDeregister();
    }
     
    public static class Task implements Runnable {
        //
        private final int id;
        private final Phaser phaser;
 
        public Task(int id, Phaser phaser) {
            this.id = id;
            this.phaser = phaser;
        }
         
        @Override
        public void run() {
            phaser.arriveAndAwaitAdvance();
            System.out.println("in Task.run(), phase: " + phaser.getPhase() + ", id: " this.id);
        }
    }
}

 

以上例子中,只有当用户按下回车之后,任务才真正开始执行。需要注意的是,arriveAndDeregister()方法不会被阻塞,并且返回到达时的phase number(arrive方法也是如此)。

 

3.3 Sample 3

CyclicBarrier支持barrier action, Phaser同样也支持。不同之处是Phaser的barrier action需要改写onAdvance方法来进行定制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import java.util.concurrent.Phaser;
 
public class PhaserTest3 {
 
    public static void main(String args[]) throws Exception {
        //
        final int count = 5;
        final int phaseToTerminate = 3;
        final Phaser phaser = new Phaser(count) {
            @Override
            protected boolean onAdvance(int phase, int registeredParties) {
                System.out.println("====== " + phase + " ======");
                return phase >= phaseToTerminate || registeredParties == 0;
            }
        };
         
        //
        for(int i = 0; i < count; i++) {
            System.out.println("starting thread, id: " + i);
            final Thread thread = new Thread(new Task(i, phaser));
            thread.start();
        }
    }
     
    public static class Task implements Runnable {
        //
        private final int id;
        private final Phaser phaser;
 
        public Task(int id, Phaser phaser) {
            this.id = id;
            this.phaser = phaser;
        }
         
        @Override
        public void run() {
            do {
                try {
                    Thread.sleep(500);
                catch(InterruptedException e) {
                    // NOP
                }
                System.out.println("in Task.run(), phase: " + phaser.getPhase() + ", id: " this.id);
                phaser.arriveAndAwaitAdvance();
            while(!phaser.isTerminated());
        }
    }
}

 

本例中的barrier action只是简单地打印了一条信息,此外在超过指定的迭代次数后终止了Phaser。

 

3.4 Sample 4

在Smaple 3的例子中,主线程在其它工作线程结束之前已经终止。如果希望主线程等待这些工作线程结束,除了使用Thread.join()之外,也可以尝试以下的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.util.concurrent.Phaser;
 
public class PhaserTest4 {
 
    public static void main(String args[]) throws Exception {
        //
        final int count = 5;
        final int phaseToTerminate = 3;
        final Phaser phaser = new Phaser(count) {
            @Override
            protected boolean onAdvance(int phase, int registeredParties) {
                System.out.println("====== " + phase + " ======");
                return phase == phaseToTerminate || registeredParties == 0;
            }
        };
         
        //
        for(int i = 0; i < count; i++) {
            System.out.println("starting thread, id: " + i);
            final Thread thread = new Thread(new Task(i, phaser));
            thread.start();
        }
         
        //
        phaser.register();
        while (!phaser.isTerminated()) {
            phaser.arriveAndAwaitAdvance();
        }
        System.out.println("done");
    }
     
    public static class Task implements Runnable {
        //
        private final int id;
        private final Phaser phaser;
 
        public Task(int id, Phaser phaser) {
            this.id = id;
            this.phaser = phaser;
        }
         
        @Override
        public void run() {
            while(!phaser.isTerminated()) {
                try {
                    Thread.sleep(500);
                catch(InterruptedException e) {
                    // NOP
                }
                System.out.println("in Task.run(), phase: " + phaser.getPhase() + ", id: " this.id);
                phaser.arriveAndAwaitAdvance();
            }
        }
    }
}

 

如果希望主线程在特定的phase结束之后终止,那么可以在主线程中调用下述方法:

1
2
3
4
5
6
7
8
9
10
11
public static void awaitPhase(Phaser phaser, int phase) {
    int p = phaser.register(); // assumes caller not already registered
    while (p < phase) {
        if (phaser.isTerminated()) {
            break// ... deal with unexpected termination
        else {
            p = phaser.arriveAndAwaitAdvance();
        }
    }
    phaser.arriveAndDeregister();
}

 

需要注意的是,awaitPhase方法中的if (phaser.isTerminated()) 分支里需要能够正确处理Phaser终止的情况。否则由于在Phaser终止之后, phaser.register()和arriveAndAwaitAdvance()方法均返回负值,那么上述方法可能陷入死循环。

 

3.5 Sample 5

以下对Phaser进行分层的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import java.util.concurrent.Phaser;
 
public class PhaserTest6 {
    //
    private static final int TASKS_PER_PHASER = 4;
 
    public static void main(String args[]) throws Exception {
        //
        final int phaseToTerminate = 3;
        final Phaser phaser = new Phaser() {
            @Override
            protected boolean onAdvance(int phase, int registeredParties) {
                System.out.println("====== " + phase + " ======");
                return phase == phaseToTerminate || registeredParties == 0;
            }
        };
         
        //
        final Task tasks[] = new Task[10];
        build(tasks, 0, tasks.length, phaser);
        for (int i = 0; i < tasks.length; i++) {
            System.out.println("starting thread, id: " + i);
            final Thread thread = new Thread(tasks[i]);
            thread.start();
        }
    }
 
    public static void build(Task[] tasks, int lo, int hi, Phaser ph) {
        if (hi - lo > TASKS_PER_PHASER) {
            for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
                int j = Math.min(i + TASKS_PER_PHASER, hi);
                build(tasks, i, j, new Phaser(ph));
            }
        else {
            for (int i = lo; i < hi; ++i)
                tasks[i] = new Task(i, ph);
        }
    }
 
    public static class Task implements Runnable {
        //
        private final int id;
        private final Phaser phaser;
 
        public Task(int id, Phaser phaser) {
            this.id = id;
            this.phaser = phaser;
            this.phaser.register();
        }
 
        @Override
        public void run() {
            while (!phaser.isTerminated()) {
                try {
                    Thread.sleep(200);
                catch (InterruptedException e) {
                    // NOP
                }
                System.out.println("in Task.run(), phase: " + phaser.getPhase()    + ", id: " this.id);
                phaser.arriveAndAwaitAdvance();
            }
        }
    }
}

 

需要注意的是,TASKS_PER_PHASER的值取决于具体的Task实现。对于Task执行时间很短的场景(也就是竞争相对激烈),可以考虑使用较小的TASKS_PER_PHASER值,例如4。反之可以适当增大TASKS_PER_PHASER。

 

java8

DoubleAccumulator

DoubleAdder:分离热点,类似ConcurrentHashMap

LongAccumulator

LongAdder

StampedLock

LongAdder:分离热点,类似ConcurrentHashMap

StampedLock

 

 

 

AQS(AbstractQueueSynchronizer)、CAS锁、CLH锁

synchronize -> RenentrantLock -> StampedLock

ong -> AtomicLong -> LongAdder

 

 

 

 

 

<audio controls="controls" style="display: none;"></audio>

分享到:
评论

相关推荐

    CountDownLatch、Semaphore等4大并发工具类详解

    Java 并发工具类是 Java 并发编程的核心组件之一,提供了多种同步结构和并发容器,帮助开发者创建高效、可靠的并发程序。本文将详细介绍 Java 并发工具类的四大类:CountDownLatch、Semaphore、CyclicBarrier 和 ...

    Java并发编程实践高清pdf及源码

    5. **并发工具类**:如`CountDownLatch`、`CyclicBarrier`、`Semaphore`和`Phaser`等,它们为多线程间的协作提供了方便。 6. **活锁与死锁**:活锁是两个或更多线程相互等待对方释放资源,导致无限期等待;死锁则是...

    JAVA并发编程实践

    根据给定文件的信息“JAVA并发编程实践”以及其描述为“Java并发学习资料”,我们可以从中提炼出关于Java并发编程的一些核心知识点。Java并发编程是Java高级特性之一,它允许开发者编写能够同时执行多个任务的程序,...

    Java并发编程全景图.pdf

    Java并发工具类扩展了基本的并发功能,例如CountDownLatch、CyclicBarrier、Semaphore和Phaser提供了不同场景下的同步支持。Exchanger用于两个线程之间交换数据。 12. 硬件和操作系统支持 Java并发编程的成功在很大...

    JAVA并发编程经典书籍

    《JAVA并发编程经典书籍》是一本深入探讨Java平台上的并发编程技术的重要著作。这本书通过详细的章节划分,系统地讲解了如何在多线程环境中编写高效、安全的代码,是Java开发者提升并发编程技能的必备参考。 书中各...

    java并发编程实战源码,java并发编程实战pdf,Java源码.zip

    5. **并发工具类**:`Semaphore`(信号量)、`CountDownLatch`、`CyclicBarrier`、`Phaser`等工具类,是解决并发问题的强大武器,能够帮助程序员协调多个线程的执行顺序。 6. **原子操作与原子变量**:`...

    Java并发编程实践-电子书1-9章pdf

    《Java并发编程实践》是Java开发者深入理解并发编程的重要参考资料,尤其对于想要提升多线程应用设计和性能优化技能的程序员来说,这本书提供了丰富的实践经验和深入的理论知识。以下是根据提供的章节内容概述的一些...

    Java并发编程实践.rar

    介绍其他并发工具,如Semaphore(信号量)、CyclicBarrier(循环屏障)、CountDownLatch(计数器门锁)和Phaser(阶段器),以及它们在并发编程中的应用场景。 第八章:并发设计模式 探讨了在并发环境中的一些设计...

    JAVA并发编程实践(中文)

    3. **并发工具类**:介绍了Java Concurrency API(JUC),包括`ExecutorService`、`Future`、`Callable`、`Semaphore`、`CountDownLatch`、`CyclicBarrier`、`Phaser`等并发工具,这些工具极大地简化了并发编程的...

    Java并发编程实战

    根据提供的文件信息,“Java并发编程实战”这本书主要聚焦于Java并发编程的核心概念和技术。下面将对并发编程的一些关键知识点进行详细解析。 ### 并发与并行 在深入讨论Java并发编程之前,我们首先需要理解并发...

    java编发编程:JUC综合讲解

    Java并发编程中的JUC(Java Util Concurrent)库是开发者处理多线程问题的关键工具,尤其在多核处理器的环境中,其重要性不言而喻。JUC库包含了一系列的类和接口,帮助开发者构建高效、稳定的并发程序。下面将详细...

    JAVA并发编程实践.pdf

    《JAVA并发编程实践》这本书是Java开发者深入理解并发编程的重要参考资料。并发编程是现代软件开发中的核心技能之一,尤其是在多核处理器普及后,利用并发能够极大地提升程序的执行效率。以下将详细介绍书中涵盖的...

    Java 并发编程示例测试

    Java并发编程是Java平台中的重要特性,它允许程序在多处理器或多线程环境中同时执行多个任务,以提高程序的效率和响应速度。在Java中,`concurrent`包提供了丰富的工具类和接口,用于实现安全、高效的并发操作。本...

    Java并发编程实战(中文版).7z

    3. **并发工具类**:介绍了许多高级并发工具,如Executor框架、Semaphore信号量、CyclicBarrier屏障、CountDownLatch倒计时器、Phaser同步阶段以及Future和Callable接口,这些工具提供了更加灵活和强大的并发控制...

    java并发编程实战

    《Java并发编程实战》这本书深入探讨了Java平台上的并发编程技术,是Java开发者提升并发处理能力的重要参考资料。书中涵盖了从基础概念到高级技巧的各种主题,旨在帮助读者理解并有效地利用多线程和并发库来构建高效...

    汪文君高并发编程实战视频资源下载.txt

    │ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...

    java 并发编程实战

    2. **Phaser**:Java 7引入的新工具,可替代CountDownLatch和CyclicBarrier,具有更灵活的分阶段并发控制。 六、线程池 Java的 **Executor框架** 提供了线程池服务,通过ThreadPoolExecutor可以定制线程池的行为,...

    Java 并发核心编程原文+译文

    2. **并发工具类**:Java 5引入了`java.util.concurrent`包,包含许多并发工具类,如`ExecutorService`、`Future`、`Semaphore`、`CountDownLatch`和`CyclicBarrier`等,它们提供了线程池、任务提交、同步控制等多种...

Global site tag (gtag.js) - Google Analytics