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();
            }
        }
    }
}

此时可以有效的解决多线成的安全性问题

原文地址:https://www.cnblogs.com/Mrchengs/p/10793730.html