zoukankan      html  css  js  c++  java
  • 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();
                }
            }
        }
    }

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

  • 相关阅读:
    自动映射失效的解决办法
    D方法 自动完成
    怎样处理包含的动态模板
    后台登陆功能的实现 SESSION
    输入框 最简单的样式
    php 添加数据库的几种方法
    php 连接数据库
    array、isset、三元运算符、find()
    foreach、count、explode(对无限级分类的语法注释-显示无限级效果)
    两种常用的启动和关闭MySQL服务
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/10793730.html
Copyright © 2011-2022 走看看