6、JUC--同步锁Lock
显示锁 Lock
在Java 5.0之前,协调共享对象的访问时可以使用的机
制只有 synchronized 和 volatile 。Java 5.0 后增加了一些
新的机制,但并不是一种替代内置锁的方法,而是当内
置锁不适用时,作为一种可选择的高级功能。
ReentrantLock 实现了 Lock 接口,并提供了与
synchronized 相同的互斥性和内存可见性。但相较于
synchronized 提供了更高的处理锁的灵活性
解决多线程安全的方法:
1、同部代码块(synchronized )隐式
2、同部方法(synchronized )隐式
3、同步锁(Lock)显示
注意:需要通过过lock()方法上锁
必须通过unlock()方法进行释放锁
实例:
卖票问题
public class TestLock { public static void main(String[] args) { Ticket t = new Ticket(); new Thread(t,"1窗口").start(); new Thread(t,"2窗口").start(); new Thread(t,"3窗口").start(); } } class Ticket implements Runnable{ private int ticket = 100; @Override public void run() { while(true){ if(ticket >0){ try { Thread.sleep(400); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "进行卖票,剩余:" + --ticket); } } } }
此时的线程是不安全的
对代码尽心修改:
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class TestLock { public static void main(String[] args) { Ticket t = new Ticket(); new Thread(t,"1窗口").start(); new Thread(t,"2窗口").start(); new Thread(t,"3窗口").start(); } } class Ticket implements Runnable{ private int ticket = 100; private Lock lock = new ReentrantLock(); @Override public void run() { while(true){ //上锁 lock.lock(); try { if(ticket >0){ try { Thread.sleep(400); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "进行卖票,剩余:" + --ticket); } } finally { //释放锁 lock.unlock(); } } } }
此时可以有效的解决多线成的安全性问题