关于lock锁
在 jdk1.5 之后,并发包中新增了 Lock 接口(以及相关实现类)用来实现锁功能,Lock 接口提供了与 synchronized 关键字类似的同步功能,但需要在使用时手动获取锁和释放锁。
lock锁 也叫显示锁
大家看下这个lock锁:
lock是个接口
这个接口下面很多锁:
对于lock锁的使用,实现生产者消费者模式的:
package com.toov5.thread; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; //共享对象 class ResLock { public boolean flag = true; public String sex; public String name; public Lock lock = new ReentrantLock(); } class inputThreadLock extends Thread { public ResLock res; public inputThreadLock(ResLock res) { this.res = res; } @Override public void run() { int count = 0; while (true) { try { res.lock.lock(); if (count == 0) { res.name = "lucy"; res.sex = "girl"; } else { res.name = "Jack"; res.sex = "boy"; } count = (count + 1) % 2; } catch (Exception e) { }finally{ res.lock.unlock(); //释放锁写在finally里面 } } } } class readThreadLock extends Thread { public ResLock res; public readThreadLock(ResLock res) { this.res = res; } @Override public void run() { while (true) { try { res.lock.lock(); System.out.println(res.name + "," + res.sex); } catch (Exception e) { e.printStackTrace(); }finally { res.lock.unlock(); } } } } public class LockTest { public static void main(String[] args) { Res res = new Res(); inputThread inputThread = new inputThread(res); readThread readThread = new readThread(res); inputThread.start(); readThread.start(); } }
注意 unlock写到finally里面哦
然后lock锁里面的 类似于 notify 和 wait的 Condition
Condition的功能类似于在传统的线程技术中的,Object.wait()和Object.notify()的功能。
使用方法:
package com.toov5.thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; //共享对象 class ResLock { public boolean flag = true; public String sex; public String name; public Lock lock = new ReentrantLock(); public Condition condition = lock.newCondition(); } class inputThreadLock extends Thread { public ResLock res; public inputThreadLock(ResLock res) { this.res = res; } @Override public void run() { if (res.flag) { try { res.condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } int count = 0; while (true) { try { res.lock.lock(); if (count == 0) { res.name = "lucy"; res.sex = "girl"; } else { res.name = "Jack"; res.sex = "boy"; } count = (count + 1) % 2; res.flag=true; res.condition.signal(); } catch (Exception e) { }finally{ res.lock.unlock(); //释放锁写在finally里面 } } } } class readThreadLock extends Thread { public ResLock res; public readThreadLock(ResLock res) { this.res = res; } @Override public void run() { while (true) { try { res.lock.lock(); if (res.flag) { res.condition.await(); } System.out.println(res.name + "," + res.sex); res.condition.signal(); } catch (Exception e) { e.printStackTrace(); }finally { res.lock.unlock(); } } } } public class LockTest { public static void main(String[] args) { Res res = new Res(); inputThread inputThread = new inputThread(res); readThread readThread = new readThread(res); inputThread.start(); readThread.start(); } }
执行结果:
Lock与synchronized 关键字的区别
Lock 接口可以尝试非阻塞地获取锁 当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁。
Lock 接口能被中断地获取锁 与 synchronized 不同,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。
Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回。
synchronize重量级锁 不可控制 释放锁 遇到异常 或者代码执行完毕后 释放锁
lock轻量级 可控释放锁 更灵活一些 lock是1.5出来的 比synchronize晚 弥补了一些不足 还有读写锁 重入锁 功能要强大一些