免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1286 | 回复: 0
打印 上一主题 下一主题

java多线程锁 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-07-09 13:05 |只看该作者 |倒序浏览
[Java]代码
  1. package org.sky.threadpool;

  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.Future;
  5. import java.util.concurrent.locks.Lock;
  6. import java.util.concurrent.locks.ReadWriteLock;
  7. import java.util.concurrent.locks.ReentrantLock;
  8. import java.util.concurrent.locks.ReentrantReadWriteLock;

  9. public class Lockers {

  10.     public static class LockTest {
  11.         Lock lock = new ReentrantLock();// 锁
  12.         double value = 0d; // 值
  13.         int addtimes = 0;

  14.         /**
  15.          * 增加value的值,该方法的操作分为2步,而且相互依赖,必须实现在一个事务中
  16.          * 所以该方法必须同步,以前的做法是在方法声明中使用Synchronized关键字。
  17.          */
  18.         public void addValue(double v) {
  19.             lock.lock();// 取得锁
  20.             System.out.println("LockTest to addValue: " + v + "   "
  21.                     + System.currentTimeMillis());
  22.             try {
  23.                 Thread.sleep(500);
  24.             } catch (InterruptedException e) {
  25.             }
  26.             this.value += v;
  27.             this.addtimes++;
  28.             lock.unlock();// 释放锁
  29.         }

  30.         public double getValue() {
  31.             return this.value;
  32.         }
  33.     }

  34.     public static void testLockTest() throws Exception {
  35.         final LockTest lockTest = new LockTest();
  36.         // 新建任务1,调用lockTest的addValue方法
  37.         Runnable task1 = new Runnable() {
  38.             public void run() {
  39.                 lockTest.addValue(1);
  40.             }
  41.         };
  42.         // 新建任务2,调用lockTest的getValue方法
  43.         Runnable task2 = new Runnable() {
  44.             public void run() {
  45.                 System.out.println("value: " + lockTest.getValue());
  46.             }
  47.         };
  48.         // 新建任务执行服务
  49.         ExecutorService cachedService = Executors.newCachedThreadPool();
  50.         Future future = null;
  51.         // 同时执行任务1三次,由于addValue方法使用了锁机制,所以,实质上会顺序执行
  52.         for (int i = 0; i < 10; i++) {
  53.             future = cachedService.submit(task1);
  54.         }
  55.         // 等待最后一个任务1被执行完
  56.         future.get();
  57.         // 再执行任务2,输出结果
  58.         future = cachedService.submit(task2);
  59.         // 等待任务2执行完后,关闭任务执行服务
  60.         future.get();
  61.         cachedService.shutdownNow();
  62.     }
  63.      
  64.     /**
  65.      * ReadWriteLock内置两个Lock,一个是读的Lock,一个是写的Lock。
  66.      * 多个线程可同时得到读的Lock,但只有一个线程能得到写的Lock,
  67.      * 而且写的Lock被锁定后,任何线程都不能得到Lock。ReadWriteLock提供的方法有:
  68.      * readLock(): 返回一个读的lock  
  69.      * writeLock(): 返回一个写的lock, 此lock是排他的。
  70.      * ReadWriteLockTest很适合处理类似文件的读写操作。
  71.      * 读的时候可以同时读,但不能写;写的时候既不能同时写也不能读。
  72.      */
  73.     public static class ReadWriteLockTest{  
  74.         // 锁  
  75.         ReadWriteLock lock = new ReentrantReadWriteLock();  
  76.         // 值  
  77.         double value = 0d;  
  78.         int addtimes = 0;  
  79.            
  80.         /**
  81.          * 增加value的值,不允许多个线程同时进入该方法
  82.          */
  83.         public void addValue(double v) {  
  84.             // 得到writeLock并锁定  
  85.             Lock writeLock = lock.writeLock();  
  86.             writeLock.lock();  
  87.             System.out.println("ReadWriteLockTest to addValue: " + v + "   "
  88.                     + System.currentTimeMillis());  
  89.             try {  
  90.                 Thread.sleep(1000);  
  91.             } catch (InterruptedException e) {  
  92.             }  
  93.             try {  
  94.                 // 做写的工作  
  95.                 this.value += v;  
  96.                 this.addtimes++;  
  97.             } finally {  
  98.                 // 释放writeLock锁  
  99.                 writeLock.unlock();  
  100.             }  
  101.         }  
  102.         /**
  103.          * 获得信息。当有线程在调用addValue方法时,getInfo得到的信息可能是不正确的。
  104.          * 所以,也必须保证该方法在被调用时,没有方法在调用addValue方法。
  105.          */
  106.         public String getInfo() {  
  107.             // 得到readLock并锁定  
  108.             Lock readLock = lock.readLock();  
  109.             readLock.lock();  
  110.             System.out.println("ReadWriteLockTest to getInfo   "
  111.                     + System.currentTimeMillis());  
  112.             try {  
  113.                 Thread.sleep(1000);  
  114.             } catch (InterruptedException e) {  
  115.             }  
  116.             try {  
  117.                 // 做读的工作  
  118.                 return this.value + " : " + this.addtimes;  
  119.             } finally {  
  120.                 // 释放readLock  
  121.                 readLock.unlock();  
  122.             }  
  123.         }  
  124.     }  

  125.     public static void testReadWriteLockTest() throws Exception {
  126.         final ReadWriteLockTest readWriteLockTest = new ReadWriteLockTest();
  127.         // 新建任务1,调用lockTest的addValue方法
  128.         Runnable task_1 = new Runnable() {
  129.             public void run() {
  130.                 readWriteLockTest.addValue(55.55);
  131.             }
  132.         };
  133.         // 新建任务2,调用lockTest的getValue方法
  134.         Runnable task_2 = new Runnable() {
  135.             public void run() {
  136.                 System.out.println("info: " + readWriteLockTest.getInfo());
  137.             }
  138.         };
  139.         // 新建任务执行服务
  140.         ExecutorService cachedService_1 = Executors.newCachedThreadPool();
  141.         Future future_1 = null;
  142.         // 同时执行5个任务,其中前2个任务是task_1,后两个任务是task_2
  143.         for (int i = 0; i < 2; i++) {
  144.             future_1 = cachedService_1.submit(task_1);
  145.         }
  146.         for (int i = 0; i < 2; i++) {
  147.             future_1 = cachedService_1.submit(task_2);
  148.         }
  149.         // 最后一个任务是task_1
  150.         future_1 = cachedService_1.submit(task_1);
  151.         // 这5个任务的执行顺序应该是:
  152.         // 第一个task_1先执行,第二个task_1再执行;这是因为不能同时写,所以必须等。
  153.         // 然后2个task_2同时执行;这是因为在写的时候,就不能读,所以都等待写结束,
  154.         // 又因为可以同时读,所以它们同时执行
  155.         // 最后一个task_1再执行。这是因为在读的时候,也不能写,所以必须等待读结束后,才能写。

  156.         // 等待最后一个task_2被执行完
  157.         future_1.get();
  158.         cachedService_1.shutdownNow();
  159.     }

  160.     public static void main(String[] args) throws Exception {
  161.         //Lockers.testLockTest();
  162.         //System.out.println("---------------------");
  163.         Lockers.testReadWriteLockTest();  
  164.     }
  165. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP