Semaphore剖析

[TOC]

Semaphore 类似于操作系统中的信号量,可以控制对互斥资源的访问线程数。

可以看到公平共享锁和非公平共享锁的区别就在是否需要判断队列中是否有已经等待的线程。公平共享锁需要先判断,非公平共享锁直接插队,尽管前面已经有线程在等待。

非公平锁acquire,内部重写,如果state<0 会被阻塞,如果成功,会扣取state值

acquire state减一 release加一

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class test {
//初始化10个信号量在信号包中,让ABCD4个线程分别去获取
public static void main(String[] args) throws InterruptedException {
Semaphore semaphore = new Semaphore(10,false);
SemaphoreTest(semaphore);
}

private static void SemaphoreTest(final Semaphore semaphore) throws InterruptedException {
//线程A初始获取了4个信号量,然后分3次释放了这4个信号量
Thread threadA = new Thread(new Runnable() {

@Override
public void run() {
try {
semaphore.acquire(8);
System.out.println(Thread.currentThread().getName() + " get 1 semaphore");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " release 1 semaphore");
semaphore.release(3);
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName() + " release 1 semaphore");
semaphore.release(5);

} catch (InterruptedException e) {
e.printStackTrace();
}

}
});
threadA.setName("threadA");
//线程B初始获取了5个信号量,然后分2次释放了这5个信号量
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("B start");
semaphore.acquire(6);
System.out.println(Thread.currentThread().getName() + " get 6 semaphore");
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + " release 6 semaphore");
semaphore.release(6);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
});
threadB.setName("threadB");

//线程C初始获取了4个信号量,然后分1次释放了这4个信号量
Thread threadC = new Thread(new Runnable() {

@Override
public void run() {
try {
System.out.println("C start");
semaphore.acquire(2);
System.out.println(Thread.currentThread().getName() + " get 2 semaphore");
Thread.sleep(2000);

System.out.println(Thread.currentThread().getName() + " release 2 semaphore");
semaphore.release(2);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
});


threadC.setName("threadC");
threadA.start();
Thread.sleep(1);
threadB.start();
Thread.sleep(3000);
threadC.start();

}
}