zoukankan      html  css  js  c++  java
  • 多线程(五)Lock接口实现锁

    一.环境

        idea

    二.Lock接口怎么实现锁

    2.1案例

    基本使用方法

    Lock lock  = new ReentrantLock();
    lock.lock();
    try{
    //可能会出现线程安全的操作
    }finally{
    //一定在finally中释放锁
    //也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
      lock.ublock();
    }

    修改之前代码

    实体

    public class UserInfo implements Serializable {
     
        private  String username;
    
        private String usersex;
    
        Lock lock=new ReentrantLock();
    }

    生产者

    public class InputThread implements Runnable {
        UserInfo userInfo=new UserInfo();
        Condition condition;
        //用来做向数据载体中放数据
        public InputThread(UserInfo userInfo,Condition condition){
            this.userInfo=userInfo;
            this.condition=condition;
        }
        public void run() {
            int count=0;
    
            while (true) {
                    userInfo.getLock().lock();
                    try {
                    if(userInfo.isFalg()){
                        try {
                            condition.await();//等待和wait()类似
                            //userInfo.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    if (count == 0) {
                        userInfo.setUsername("小明");
                        userInfo.setUsersex("男");
                    } else if (count == 1) {
                        userInfo.setUsername("小红");
                        userInfo.setUsersex("女");
                    }
                    userInfo.setFalg(true);
                    condition.signal();//唤醒一个线程和notify()方法类似
                        // this.notify();
                    count = (count + 1) % 2;
                }catch (Exception e){
    
                    }finally {
                    userInfo.getLock().unlock();
                    }
            }
        }
    }

    消费者

    public class OutputThread implements Runnable {
    
        UserInfo userInfo=new UserInfo();
        Condition condition;
    
    
        public OutputThread( UserInfo userInfo,Condition condition){
            this.userInfo=userInfo;
            this.condition=condition;
        }
    
        public void run() {
    
            while (true) {
                try {
                    userInfo.getLock().lock();//开启锁
                    if(!userInfo.isFalg()){
                        try {
                            condition.await();//等待和wait()类似
                           // userInfo.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    if (userInfo != null) {
                        System.out.println("userName:" + userInfo.getUsername() + ",userSex:" + userInfo.getUsersex());
                    }
                    condition.signal();//唤醒一个线程和notify()方法类似
    
                    userInfo.setFalg(false);
                }catch (Exception e){
    
                }finally {
                    userInfo.getLock().unlock();//释放锁
                }
    
    
            }
    
        }
    }

    测试

     public static void main(String[] args) {
            UserInfo userInfo=new UserInfo();
            Condition condition = userInfo.getLock().newCondition();
            OutputThread outputThread=new OutputThread(userInfo,condition);
            InputThread inputThread=new InputThread(userInfo,condition);
            Thread t1=new Thread(outputThread);
            Thread t2=new Thread(inputThread);
            t1.start();
            t2.start();
        }

    2.2加锁的原则

    加锁的目的是为了保证多线程数据的同步,如果想保证线程同步需要保证:

    1.使用的是通一把锁

    2.如果是用的是lock锁那么提供方法的Condition类也要保证是同一个

    2.3 Condition

    详情请见http://www.importnew.com/9281.html

    Condition condition = lock.newCondition();

    res. condition.await();  类似wait

    res. Condition. Signal() 类似notify

    三.synchronized和lock的区别

    1.Lock 接口可以尝试非阻塞地获取锁 当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁。

    2.Lock 接口能被中断地获取锁 与 synchronized 不同,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。

    3.Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回。

    四.wait与sleep区别

    1.对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

    2.sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

    3.在调用sleep()方法的过程中,线程不会释放对象锁。而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备

    获取对象锁进入运行状态。

  • 相关阅读:
    中断和异常
    MATLAB总结二
    关于在写第一个模式识别大作业中遇到的几个问题的总结
    学习QT——GUI的基础用法(2)
    Matlab练习——rpy2tr函数与自己实现的ZYX欧拉角的结果不同的问题
    PHP之文件的锁定、上传与下载
    PHP之文件目录基础操作
    PHP之会话控制小结
    PHP之curl
    PHP之数组函数归类
  • 原文地址:https://www.cnblogs.com/wy0119/p/9004343.html
Copyright © 2011-2022 走看看