java之ReentrantLock公平锁和非公平锁
2016-05-19 23:31
447 查看
大多数情况下,大家可能都会选择使用synchronized来加锁,ReentrantLock确实是一种高级加锁工具,在确实需要一些 synchronized 所没有的特性的时候,比如时间锁等候、可中断锁等候、无块结构锁、多个条件变量或者锁投票。
以下实现公平锁和非公平锁,公平锁在性能上会多消耗点
package com.cmcc.web.test.lock; import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockTest { private static final ReentrantLock lock = new ReentrantLock(); private static final ReentrantLock fairlock = new ReentrantLock(true); private int n; public static void main(String[] args) { ReentrantLockTest rlt = new ReentrantLockTest(); for (int i = 0; i < 100; i++) { Thread nonT = new Thread(new NonFairTestThread(rlt)); nonT.setName("nonFair[" + (i + 1) + "]"); nonT.start(); Thread fairT = new Thread(new FairTestThread(rlt)); fairT.setName("fair[" + (i + 1) + "]"); fairT.start(); } } // 非公平锁 static class NonFairTestThread implements Runnable { private ReentrantLockTest rlt; public NonFairTestThread(ReentrantLockTest rlt) { this.rlt = rlt; } public void run() { lock.lock(); try { rlt.setNum(rlt.getNum() + 1); System.out.println(Thread.currentThread().getName() + " nonfairlock***************" + rlt.getNum()); } finally { lock.unlock(); } } } // 公平锁 static class FairTestThread implements Runnable { private ReentrantLockTest rlt; public FairTestThread(ReentrantLockTest rlt) { this.rlt = rlt; } public void run() { fairlock.lock(); try { rlt.setNum(rlt.getNum() + 1); System.out.println(Thread.currentThread().getName() + " fairlock=======" + rlt.getNum() + " " + fairlock.getHoldCount() + " queuelength=" + fairlock.getQueueLength()); } finally { fairlock.unlock(); } } } public void setNum(int n) { this.n = n; } public int getNum() { return n; } }
以下是同时使用多个锁的情况下
package com.cmcc.web.test.lock; import java.util.concurrent.locks.ReentrantLock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TestLock { private final static Logger logger = LoggerFactory.getLogger(TestLock.class); private static final ReentrantLock lock = new ReentrantLock(true); private static final ReentrantLock lock1 = new ReentrantLock(true); // 设置一个锁,然后休眠,另外一个线程获取这个锁的时候如果这个锁有人在使用的就不跳过了 public static void main(String[] args) throws InterruptedException { Test1 test1 = new Test1(); test1.start(); Thread.sleep(500); Test2 test2 = new Test2(); test2.start(); } static class Test1 extends Thread { public void run() { lock.lock(); lock1.lock(); for (int i=0;i<2;i++) { logger.info("lock1被我锁住了"); if (i==0) { lock.unlock(); } if (i==1) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } lock1.unlock(); } } // lock.lock(); // try { // logger.info(this.hashCode() + this.hashCode() + "开始休眠"); // //Thread.sleep(5000); // logger.info(this.hashCode() + "开始结束"); // }catch (Exception e) { // // } // finally { // lock.unlock(); // } } } static class Test2 extends Thread { public void run() { //如果锁可用,则获取锁,并立即返回值 true。 //如果锁不可用,则此方法将立即返回值 false。 boolean lockBoolean = lock1.tryLock(); if (lockBoolean) { logger.info(this.hashCode() + "当前锁1可以使用"); } else { logger.info(this.hashCode() + "当前锁1不可以使用"); } logger.info(this.hashCode() + "那我就等着吧"); lock.lock(); try { logger.info(this.hashCode() + "我得到锁了"); }catch (Exception e) { } finally { lock.unlock(); } lock1.lock(); try { logger.info(this.hashCode() + "我得到锁了1"); }catch (Exception e) { } finally { lock1.unlock(); } } } }
相关文章推荐
- Java Core和HeapDump
- 深入分析 Java 中的中文编码问题(1)
- Java发展历史
- 基于CXF Servlet方式发布Restful的Web服务(入门篇)
- 包装类
- Java编码浅析(注意区分三个概念)(转)
- 第一章 答疑摘选
- java-ThreadLocal是解决线程安全问题
- 说说eclipse调优,缩短启动时间
- Mybatis_java项目
- Java注册帐号邮箱激活验证实现
- Spring学习(三)IOC控制反转与DI依赖注入
- JavaMai——邮箱验证用户注册
- POJO——简单Java对象
- Windows 下的 Java JDK安装
- 4,由spring展开的串烧
- java- List
- [Java]泛型总结
- 越来越好玩,SPRINGMVC
- gml文件读写 hashmap用法与遍历 以及 文本文件解析方法