java lock 实例_Java并发编程之——Lock(重入锁,读写锁)及Condition示例

在JDK5的并发包中有一个子包为java.concurrent.locks,它下面定义了三个接口Lock,ReadWriteLock,Condition,分别为重入锁,读写锁,锁条件判断

LOCK:

Lock与java关键字(synchronized)具有相同的功能,但它更加灵活。ReentrantLock作为Lock接口的实现类,被作为Java语言中synchronized功能的替代,它们具有相同的内存意义,相同的锁定,但在争用条件下却有更好的性能,此为它还有synchronized没有提供的其它特性。但就实际应用来说,由于内部锁是内置于Java虚拟机中的,它能够进行优化,因此未来的性能改进可能更倾向于内部锁,而不是重入锁。综上所述,除非你的应用程序需要发在Java 5.0上,或者需要使用重入锁的可伸缩性,否则就应该选择内部锁。

总之,ReentrantLock锁与Java内在锁相比有下面的特点:

1)ReentrantLock必须在 finally 块中释放锁,而使用synchronized同步,JVM 将确保锁会获得自动释放。

2)与目前的 synchronized 实现相比,争用下的 ReentrantLock 实现更具可伸缩性。

3)对于ReentrantLock ,可以有不止一个条件变量与它关联。(Condition后面会说到)

4)允许选择想要一个公平锁,还是一个不公平锁。(new ReentrantLock(false)非公平锁,非公平锁执行效率会更高)

5)除非你对 Lock 的某个高级特性有明确的需要,或者有明确的证据表明在特定情况下,同步已经成为可伸缩性的瓶颈,否则还是应当继续使用synchronized。

6)Lock 类只是普通的类,JVM 不知道具体哪个线程拥有 Lock 对象。而且,几乎每个开发人员都熟悉 synchronized,它可以在 JVM 的所有版本中工作。

Condition:

类似于java中原来线程交互所用的wait,notify和notifyAll方法在新的并发包中基于重入锁机制引入了Condition接口,Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set),就是多路等待。Condition 的方法与 wait 、notify 和 notifyAll 方法类似,分别命名为 await 、 signal和singalAll因为它们不能覆盖Object上的对应方法。

下面是一个多路条件等待按顺序执行的例子,给定一个0,按1,2,3,这样的顺序依次加一次,总共加10次,并输出每次加后的结果,模拟让多线程来做:

48304ba5e6f9fe08f3fa1abda7d326ab.png

1 importjava.util.concurrent.locks.Condition;

2 importjava.util.concurrent.locks.Lock;

3 importjava.util.concurrent.locks.ReentrantLock;

4

5 public classConditionTest {

6

7 /**

8 * @paramargs

9 */

10 public static voidmain(String[] args) {

11 for (int i = 0; i < 10; i++) {

12 new Thread(newRunnable() {

13

14 @Override

15 public voidrun() {

16 newTest1().sub1();

17

18 }

19 }).start();

20

21 new Thread(newRunnable() {

22

23 @Override

24 public voidrun() {

25 newTest1().sub2();

26

27 }

28 }).start();

29

30 new Thread(newRunnable() {

31

32 @Override

33 public voidrun() {

34 newTest1().sub3();

35

36 }

37 }).start();

38 }

39 }

40

41 }

42

43 classTest1 {

44 public static int i = 0;

45 public static int conNum = 1;

46 //此处注意锁和condition也要定义成静态的,不然就有多把锁和condition了,相当于没加一样。

47 public static Lock lock = new ReentrantLock(false);

48 public static Condition con1 =lock.newCondition();

49 public static Condition con2 =lock.newCondition();

50 public static Condition con3 =lock.newCondition();

51

52 //方法1对i进行加1

53 public voidsub1() {

54 lock.lock();

55 try{

56 while (conNum != 1) {

57 try{

58 con1.await();

59 } catch(InterruptedException e) {

60 e.printStackTrace();

61 }

62 }

63 i++;

64 System.out.print(i + ",");

65 conNum = 2;

66 con2.signal();

67 } finally{

68 lock.unlock();

69 }

70

71 }

72

73 //方法2对i加2

74 public voidsub2() {

75 lock.lock();

76

77 try{

78 while (conNum != 2) {

79 try{

80 con2.await();

81 } catch(InterruptedException e) {

82 e.printStackTrace();

83 }

84 }

85 i = i + 2;

86 System.out.print(i + ",");

87 conNum = 3;

88 con3.signal();

89 } finally{

90 lock.unlock();

91 }

92

93 }

94

95 //方法3对i加3;

96 public voidsub3() {

97 lock.lock();

98 try{

99

你可能感兴趣的:(java,lock,实例)