zoukankan      html  css  js  c++  java
  • Lock 和 synchronized的区别

    1、线程生命周期

    线程总共有5大状态

    • 新建状态:新建线程对象,并没有调用start()方法之前

    • 就绪状态:调用start()方法之后线程就进入就绪状态,但是并不是说只要调用start()方法线程就马上变为当前线程,在变为当前线程之前都是为就绪状态。值得一提的是,线程在睡眠和挂起中恢复的时候也会进入就绪状态哦。

    • 运行状态:线程被设置为当前线程,开始执行run()方法。就是线程进入运行状态

    • 阻塞状态:线程被暂停,比如说调用sleep()方法后线程就进入阻塞状态

    • 死亡状态:线程执行结束

      

    锁类型

    • lock():获取锁,如果锁被暂用则一直等待

    • unlock():释放锁

    • tryLock(): 注意返回类型是boolean,如果获取锁的时候锁被占用就返回false,否则返回true

    • tryLock(long time, TimeUnit unit):比起tryLock()就是给了一个时间期限,保证等待参数时间

    • lockInterruptibly():用该锁的获得方式,如果线程在获取锁的阶段进入了等待,那么可以中断此线程,先去做别的事

     

    package cn.xiang.thread.lock;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * lock锁学习demo
     * 总结:
     *         1、使用lock.lock()方法可以将对象锁定。同时必须在finally将锁释放lock.unlock(),否则其他对象获取不了该锁。
     *         2、如果是线程内新定义的对象,那么有无锁都会异步执行,并不同步。
     * @author 向宁
     *日期:2018年4月11日
     *时间:下午3:26:06
     *
     */
    public class LockDemo01 {
        /**
         * 创建锁
         */
        private Lock lock = new ReentrantLock();
        
        /**
         * 需要同步执行的方法
         * @param thread
         * @throws InterruptedException 
         */
        public void lockMethod(){
            System.out.println("还没开始锁定");
            lock.lock();
            Thread thread = Thread.currentThread();
            System.out.println("我是" + thread.getName() + "!正在使用锁");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
            
        }
        
        public static void main(String[] args) {
            final LockDemo01 lockDemo = new LockDemo01();
            Thread t1 = new Thread(){
                @Override
                public void run(){
                    lockDemo.lockMethod();
                }
            };
            Thread t2 = new Thread(){
                @Override
                public void run(){
                    lockDemo.lockMethod();
                }
            };
            t1.start();
            t2.start();
        }
    }
    LockDemo01

    结果如下:

      

    package cn.xiang.thread.lock;
    /**
     * lock.tryLock()
     *         可if判断该代码是否被锁定。如果被锁定,则不执行。
     * lock.tryLock(time, unit)
     *         给一个等待时间,等待时间过后,如果锁定被释放,则可以直接进入。如果等待时间已过,还不释放。则直接执行else
     * 
     */
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class LockDemo02 {
        private Lock lock = new ReentrantLock();
        /**
         * 需要同步的方法
         */
        public void lockMethod(){
            try {
                System.out.println("开始执行方法");
                if (lock.tryLock(1, TimeUnit.SECONDS)) {
                    //如果当前已经被锁定
                    try {
                        System.out.println("我是线程:" + Thread.currentThread().getName() + "!我已经拿到了该锁!");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally{
                        lock.unlock();
                    }
                    
                }else{
                    System.out.println("我是线程:" + Thread.currentThread().getName() + "!我没有拿到该锁,就不要了!");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) {
            final LockDemo02 lockDemo = new LockDemo02();
            Thread t1 = new Thread(){
                @Override
                public void run(){
                    lockDemo.lockMethod();
                }
            };
            Thread t2 = new Thread(){
                @Override
                public void run(){
                    lockDemo.lockMethod();
                }
            };
            Thread t3 = new Thread(){
                @Override
                public void run(){
                    lockDemo.lockMethod();
                }
            };
            t1.start();
            t2.start();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            t3.start();
        }
    }
    LockDemo02

    结果如下:

      

    以下是一个简单的死锁

    package cn.xiang.thread;
    
    public class ThreadDeadLock03 {
        
        public static void main(String[] args) {
            LockDemo04 lock = new LockDemo04(false);
            new Thread(lock).start();
            new Thread(lock).start();
            
        }
    }
    
    class LockDemo04 implements Runnable{
        private boolean flag;
        private Object obj1 = new Object();
        private Object obj2 = new Object();
        public LockDemo04(boolean flag){
            this.flag = flag;
        }
        @Override
        public void run() {
            flag = !flag;
            try {
                if(flag){
                    synchronized(obj1){
                        System.out.println("已经拿到obj1的对象锁");
                        Thread.sleep(1000);
                        System.out.println("准备拿obj2的对象锁");
                        synchronized(obj2){
                            System.out.println("已经拿到obj2的对象锁,表示没有发生死锁");
                        }
                    }
                }else{
                    synchronized(obj2){
                        System.out.println("已经拿到obj2的对象锁");
                        Thread.sleep(1000);
                        System.out.println("准备拿obj1的对象锁");
                        synchronized(obj1){
                            System.out.println("已经拿到obj1的对象锁,表示没有发生死锁!");
                        }
                    }
                }
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }

    效果:

      

  • 相关阅读:
    移动端必备rem布局
    个人工作经历、近些日来一些面试总结
    JavaScript面向对象核心知识归纳
    微信开发工具下载地址
    每天运动步数周月切换显示
    爬虫-requests
    django请求生命周期,FBV和CBV,ORM拾遗,Git
    Django + Uwsgi + Nginx 的生产环境部署
    沈阳润才教育CRM
    网络编程
  • 原文地址:https://www.cnblogs.com/xiangyuqi/p/8796523.html
Copyright © 2011-2022 走看看