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

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

  • 相关阅读:
    单例设计模式
    MySQL数据类型
    MySQL创建、修改、删除数据库
    HTTP请求与响应
    netcore在CentOS7 下使用处理图片的问题
    SQL删除重复数据
    不同浏览器对cookie大小与个数的限制
    asp.net实现SQL2005的通知数据缓存
    MS SQL 设置自增长字段默认值
    MS SQL 批量操作
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/10793730.html
Copyright © 2020-2023  润新知