先谈谈闭锁和栅栏的区别:
1.关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行。
2.闭锁用于等待某一个事件的发生,举例:CountDownLatch中await方法等待计数器为零时,所有事件才可继续执行。而栅栏是等待其他线程到位,所有事件才可继续下一步。例如:几个家庭决定在某个地方集合:“所有人6:00在麦当劳碰头,到了以后要等其他人,之后再讨论下一步要做的事情”。
Semaphore(闭锁)
这个东西和之前的synchronized干的事差不多。
synchronized保证了,我管理的那部分代码同一时刻只有一个线程能访问
Semaphore保证了,我管理的那部分代码同一时刻最多可以有n个线程访问
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
|
import
java.util.concurrent.ExecutorService; import
java.util.concurrent.Executors; import
java.util.concurrent.Semaphore; public class SemaphoreTest
{ public static void main(String[]
args) { ExecutorService
service = Executors.newCachedThreadPool(); final
Semaphore sp = new Semaphore(3); for ( int i=0;i<10;i++){ Runnable
runnable = new Runnable(){ public void run(){ try { sp.acquire(); } catch (InterruptedException
e1) { e1.printStackTrace(); } System. out .println( "线程" +
Thread.currentThread().getName() + "进入,当前已有" +
(3-sp.availablePermits()) + "个并发" ); try { Thread.sleep(( long )(Math.random()*10000)); } catch (InterruptedException
e) { e.printStackTrace(); } System. out .println( "线程" +
Thread.currentThread().getName() + "即将离开" ); sp.release(); //下面代码有时候执行不准确,因为其没有和上面的代码合成原子单元 System. out .println( "线程" +
Thread.currentThread().getName() + "已离开,当前已有" +
(3-sp.availablePermits()) + "个并发" ); } }; service.execute(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
|
线程pool-1-thread-2进入,当前已有2个并发 线程pool-1-thread-1进入,当前已有2个并发 线程pool-1-thread-3进入,当前已有3个并发 线程pool-1-thread-1即将离开 线程pool-1-thread-1已离开,当前已有2个并发 线程pool-1-thread-4进入,当前已有3个并发 线程pool-1-thread-3即将离开 线程pool-1-thread-3已离开,当前已有2个并发 线程pool-1-thread-5进入,当前已有3个并发 线程pool-1-thread-2即将离开 线程pool-1-thread-2已离开,当前已有2个并发 线程pool-1-thread-6进入,当前已有3个并发 线程pool-1-thread-4即将离开 线程pool-1-thread-4已离开,当前已有2个并发 线程pool-1-thread-7进入,当前已有3个并发 线程pool-1-thread-5即将离开 线程pool-1-thread-5已离开,当前已有2个并发 线程pool-1-thread-8进入,当前已有3个并发 线程pool-1-thread-8即将离开 线程pool-1-thread-9进入,当前已有3个并发 线程pool-1-thread-8已离开,当前已有3个并发 线程pool-1-thread-6即将离开 线程pool-1-thread-6已离开,当前已有2个并发 线程pool-1-thread-10进入,当前已有3个并发 线程pool-1-thread-10即将离开 线程pool-1-thread-10已离开,当前已有2个并发 线程pool-1-thread-7即将离开 线程pool-1-thread-7已离开,当前已有1个并发 线程pool-1-thread-9即将离开 线程pool-1-thread-9已离开,当前已有0个并发 |