该文章主要讲解如何快速应用Lock和synchronized
读者可以自行学习Lock和synchronized系统级比较;可参考并发实战等,自己决定什么场景下使有哪种锁
Lock使用案例:
public class Person {
//两个线程同时调用这个方法 public void say(String msg){ int len = msg.length(); for(int i=0;i<len;i++){ System.out.print(msg.charAt(i)); } System.out.println(); } }
public class LockTest { public static void main(String[] args) { Person person = new Person(); new Thread(new Runnable(){ @Override public void run() { while(true){ try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } person.say("haohaoxuexi"); } } }).start(); new Thread(new Runnable(){ @Override public void run() { while(true){ try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } person.say("tiantianxiangshang"); } } }).start(); } }
输出的结果:
haohaoxuexi
tianhaohaoxuexitianxiangshang
hatiantianxiangshangoha
oxuexi
htiantianxiangshangaohaoxuexi
以上结果是随机生成的,每次的结果可能都不一样;主要证明并发一个对象方法时候存在线程安全问题
修改方法:
public class Person {
//为对象创建一把锁 Lock lock = new ReentrantLock(); public void say(String msg){ int len = msg.length();
//加锁 lock.lock(); try{ for(int i=0;i<len;i++){ System.out.print(msg.charAt(i)); } System.out.println(); }finally{
//解锁 lock.unlock(); } } }
此时是结果正常:
tiantianxiangshang
haohaoxuexi
tiantianxiangshang
haohaoxuexi
tiantianxiangshang
haohaoxuexi
tiantianxiangshang
haohaoxuexi
基于Lock读写锁的案例:
public class Cache { //创建一个缓存 private static Map<String, Object> cache = new HashMap<String, Object>(); //创建读写锁 private static ReadWriteLock rwl = new ReentrantReadWriteLock(); public static Object getData(String key){ //加读锁 rwl.readLock().lock(); Object value = null; try{ value = cache.get(key); if(value == null){ //释放读锁 rwl.readLock().unlock(); //加写锁 rwl.writeLock().lock(); try{ if(value==null){ value = "查询介质获取数据"; cache.put(key, value); } }finally{ //加读锁 rwl.readLock().lock(); //释放写锁 rwl.writeLock().unlock(); } } }finally{ //释放读锁 rwl.readLock().unlock(); } return value; } }
synchronized使用案例
public class Person { //两个线程同时调用这个方法 public void say(String msg){ int len = msg.length(); for(int i=0;i<len;i++){ System.out.print(msg.charAt(i)); } System.out.println(); } } 把上述代码修改成以下即可 public class Person { public synchronized void say(String msg){ int len = msg.length(); for(int i=0;i<len;i++){ System.out.print(msg.charAt(i)); } System.out.println(); } } 或者修改成以下代码 public class Person { public void say(String msg){ int len = msg.length(); synchronized(Person.class){ for(int i=0;i<len;i++){ System.out.print(msg.charAt(i)); } System.out.println(); } } }