展会信息港展会大全

Java ReentrantLock,ReentrantReadWriteLock和Condition的简单描述示例
来源:互联网   发布日期:2016-01-19 12:26:12   浏览:3649次  

导读: lock 框架 java util concurrent lock 框架是 JDK5 0 后新增的特性,作用呢是准备用来替代 synchronized 语义和 volatile 声明,属于高帅富性能,对于初级开发来说平时开发可能用不上,因为synch ...

## lock 框架 ##

java.util.concurrent.lock 框架是 JDK5.0 后新增的特性,作用呢是准备用来替代 synchronized 语义和 volatile 声明,属于高帅富性能,对于初级开发来说平时开发可能用不上,因为synchronized 已能很好的应用于大部分场景。如果你的项目里的多线程模块需要用更高的性能,更高的灵活性,更好的伸缩性,那么可以把原来的synchronized块替 换成lock框架下的 ReetrantLock, ReetantReadWriteLock,Condition来搭配实现。

下面贴上这3个包的简单示例代码。

1.ReetrantLock

ReetrantLock相比于synchronized一个很明显的机制差异就是ReetrantLock 可以中断一个正在等候获得锁的线程,也可以通过投票得到锁,如果不想等下去,那么就是它了。

ReetrantLock简单示例代码如下:

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

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class ThreadDemo1 {

/** * @param args */

public static void main(String[] args) {

final Output output = new Output();

new Thread(new Runnable() {

@Override

public void run() {

while (true) {

output.print("Hello Beauty");

}

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

while (true) {

output.print("HelloWorld");

}

}

}).start();

}

}

class Output {

Lock lock = new ReentrantLock();

public void print(String name) {

lock.lock();

try {

for (int i = 0; i < name.length(); i++) {

System.out.print(name.charAt(i));

}

System.out.println();

} finally {

lock.unlock();// 请记住一定要在finally块里释放锁,ReentrantLock不会自动释放锁,不然程序抛出异常

}

}

}

ReentrantReadWriteLock

ReentrantReadWriteLock是针对于共享数据的读写优化,多线程在读操作是不会产生互斥的,而在写操作时才有互斥,在大数据量的 同时读写操作时,会效率很多。

ReentrantReadWriteLock简单示例代码如下:

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.Random;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ThreadDemo2 {

/**

* @param args

*/

public static void main(String[] args) {

final Queue queue = new Queue();

new Thread(new Runnable() {

@Override

public void run() {

while(true){

queue.getData();

}

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

while(true){

queue.putData();

}

}

}).start();

}

}

class Queue{

private Object data;//被共享

ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

public void getData(){

rwl.readLock().lock();//不互斥,大家都可以访问

try{

System.out.println(Thread.currentThread().getName()+"准备读取数据");

try {

Thread.sleep(new Random().nextInt(1000));

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"获得数据"+this.data);

}finally{

rwl.readLock().unlock();

}

}

public void putData(){

rwl.writeLock().lock();//写锁互斥,一个线程进来,读写的其它线程都不能访问

try{

System.out.println(Thread.currentThread().getName()+"准备存入数据");

this.data = new Random().nextInt(500);

try {

Thread.sleep(4000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"存入数据"+this.data);

}finally{

rwl.writeLock().unlock();//记住此操作不可省略

}

}

}

Condition

Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。线程之间除了同步互斥,还要考虑通信。在Java5之前我们的通信方式为:wait 和 notify。那么Condition的优势是支持多路等待,就是我们可以定义多个Condition,每个condition控制线程的一条执行通路。 传统方式只能是一路等待。

ReetrantLock简单示例代码如下:

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

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class ThreadDemo3 {

public static void main(String[] args) {

final Bus bus = new Bus();

new Thread(new Runnable() {

@Override

public void run() {

for(int i = 1; i <= 50;i++){

bus.sub1();

}

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

for(int i = 1; i <= 50;i++){

bus.sub2();

}

}

}).start();

new Thread(new Runnable() {

@Override

public void run() {

for(int i = 1; i <= 50;i++){

bus.sub3();

}

}

}).start();

}

}

class Bus{

int flag = 1;

Lock lock = new ReentrantLock();

Condition condition1 = lock.newCondition();

Condition condition2 = lock.newCondition();

Condition condition3 = lock.newCondition();

public void sub1(){

lock.lock();

try{

while(flag!=1){

try {

//this.wait();

condition1.await();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

for(int i = 1; i <= 10; i++){

System.out.println("老大循环"+i+"次");

}

//this.notify();

condition2.signal();

flag = 2;

}finally{

lock.unlock();

}

}

public void sub2(){

lock.lock();

try{

while(flag!=2){

try {

//this.wait();

condition2.await();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

for(int i = 1; i <= 20;i++){

System.out.println("老二"+i+"次");

}

//this.notify();

condition3.signal();

flag = 3;

}finally{

lock.unlock();

}

}

public void sub3(){

lock.lock();

try{

while(flag!=3){

try {

//this.wait();

condition3.await();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

for(int i = 1; i <= 30;i++){

System.out.println("老三"+i+"次");

}

//this.notify();

condition1.signal();

flag = 1;

}finally{

lock.unlock();

}

}

}

赞助本站

人工智能实验室

相关热词: Java ReentrantLock android开发

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港