在Java多线程中,可以使用关键字Synchronized实现线程之间互斥。在JDK1.5之后,提供了线程并发库java.util.concurrent用于操作多线程,其中包含了java.util.concurrent.atomic和java.util.concurrent.lock。atomic可以实现数据或变量的原子性操作,而lock可以实现线程互斥,可以实现读写锁,跟Synchronized一样同属于可重入锁,但在使用上比Synchronized更加灵活。

在代码中,可以通过new ReentrantLock()创建一个lock锁,调用lock()实现对代码上锁,调用unlock()可以解锁。当然,为了保证代码运行出现异常时也能解锁,应该把上锁的代码用try包裹起来,并在finally里解锁,具体代码实现如下:


[java] 

1. public class Main {  
2. //静态内部类实现线程共享  
3. static class Example{  
4. //创建lock  
5. new ReentrantLock();  
6. public void outPut(String str){  
7. //上锁  
8.             lock.lock();  
9. try{  
10. for(int i=0;i<str.length();i++){  
11.                     System.out.print(str.charAt(i));  
12.                 }  
13. "\n");  
14. finally {  
15. //解锁  
16.                 lock.unlock();  
17.             }  
18.         }  
19.     }  
20.   
21. public static void main(String[] args) {  
22. final Example example = new Example();  
23. new Thread(new Runnable() {  
24. @Override  
25. public void run() {  
26. while (true){  
27. "str1");  
28.                 }  
29.             }  
30.         }).start();  
31. new Thread(new Runnable() {  
32. @Override  
33. public void run() {  
34. while (true){  
35. "str2");  
36.                 }  
37.             }  
38.         }).start();  
39.     }  
40. }


对于lock的读写锁,可以通过new ReentrantReadWriteLock()获取到一个读写锁。所谓读写锁,便是多线程之间读不互斥,读写互斥。读写锁是一种自旋锁,如果当前没有读者,也没有写者,那么写者可以立刻获得锁,否则它必须自旋在那里,直到没有任何写者或读者。如果当前没有写者,那么读者可以立即获得该读写锁,否则读者必须自旋在那里,直到写者释放该锁。具体代码实现如下:


[java]

1. public class Main {  
2. //静态内部类实现线程共享  
3. static class Example{  
4. //创建lock  
5. new ReentrantReadWriteLock();  
6. //读操作  
7. public void read(){  
8. //获取读锁并上锁  
9.             lock.readLock().lock();  
10. try{  
11. "读线程开始");  
12. 1000);  
13. "读线程结束");  
14. catch (Exception e){  
15.                 e.printStackTrace();  
16. finally{  
17. //解锁  
18.                 lock.readLock().unlock();  
19.             }  
20.         }  
21. //写操作  
22. public void write(){  
23. //获取写锁并上锁  
24.             lock.writeLock().lock();  
25. try{  
26. "写线程开始");  
27. 1000);  
28. "写线程结束");  
29. catch (Exception e){  
30.                 e.printStackTrace();  
31. finally {  
32. //解锁  
33.                 lock.writeLock().unlock();  
34.             }  
35.         }  
36.     }  
37.   
38. public static void main(String[] args) {  
39. final Example example = new Example();  
40. new Thread(new Runnable() {  
41. @Override  
42. public void run() {  
43. while (true){  
44.                     example.read();  
45.                     example.write();  
46.                 }  
47.             }  
48.         }).start();  
49. new Thread(new Runnable() {  
50. @Override  
51. public void run() {  
52. while (true){  
53.                     example.read();  
54.                     example.write();  
55.                 }  
56.             }  
57.         }).start();  
58.     }  
59. }


运行结果:

java中redission中lock锁过期时间和锁自动续期_java

根据结果可以发现,多线程下ReentrantReadWriteLock可以多线程同时读,但写的话同一时刻只有一个线程执行。

最后说一说读写锁的应用场景,我们可以利用读写锁可是实现一个多线程下数据缓存的功能,具体实现思路如下:


[java] 

1. class dataCatch{  
2. //缓存的数据  
3. public volatile Boolean isCatch = false; //是否有缓存  
4. new ReentrantReadWriteLock(); //生成读写锁  
5.   
6. public void process(){  
7. //先加读锁,此时数据不会被修改  
8. //数据没有缓存  
9. if(!isCatch){  
10. //解读锁  
11. //加写锁,此时数据不会被读到  
12. /********
13.              *
14.              * 执行数据查询操作并赋值给data
15.              *
16.              ********/  
17. true;  
18. //先加读锁后解写锁  
19.             lock.writeLock().lock();  
20.         }  
21. /********
22.          *
23.          * 放回data数据给用户
24.          *
25.          ********/  
26. //解读锁  
27.     }  
28. }