• 奇葩锁


    一、改变了锁对象

    package com.lanyun.hadoop2;
    
    /**
     * 锁对象的改变问题
     *
     */
    public class ChangeLock {
    
        private String lock = "lock";
    
        private void method() {
            synchronized (lock) {
                try {
                    System.out.println("当前线程 : " + Thread.currentThread().getName() + "开始");
                    lock = "change lock";
                    Thread.sleep(2000);
                    System.out.println("当前线程 : " + Thread.currentThread().getName() + "结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) {
    
            final ChangeLock changeLock = new ChangeLock();
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    changeLock.method();
                }
            }, "t1");
            Thread t2 = new Thread(new Runnable() {
                public void run() {
                    changeLock.method();
                }
            }, "t2");
            t1.start();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t2.start();
        }
    }

    本来打算让t1先执行,t1执行完成之后t2再执行,但是t1线程将锁对象改变了,所以可以说t1线程获取的是字符串“lock”的对象锁,t2线程获取的是字符串“change lock”的对象锁。

    二、死锁问题

    package com.lanyun.hadoop2;
    /**
     * 死锁问题,在设计程序时就应该避免双方相互持有对方的锁的情况
     *
     */
    public class DeadLock implements Runnable{
    
        private String tag;
        private static Object lock1 = new Object();
        private static Object lock2 = new Object();
        
        public void setTag(String tag){
            this.tag = tag;
        }
        
        public void run() {
            if(tag.equals("a")){
                synchronized (lock1) {
                    try {
                        System.out.println("当前线程 : "  + Thread.currentThread().getName() + " 进入lock1执行");
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock2) {
                        System.out.println("当前线程 : "  + Thread.currentThread().getName() + " 进入lock2执行");
                    }
                }
            }
            if(tag.equals("b")){
                synchronized (lock2) {
                    try {
                        System.out.println("当前线程 : "  + Thread.currentThread().getName() + " 进入lock2执行");
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock1) {
                        System.out.println("当前线程 : "  + Thread.currentThread().getName() + " 进入lock1执行");
                    }
                }
            }
        }
        
        public static void main(String[] args) {
            
            DeadLock d1 = new DeadLock();
            d1.setTag("a");
            DeadLock d2 = new DeadLock();
            d2.setTag("b");
             
            Thread t1 = new Thread(d1, "t1");
            Thread t2 = new Thread(d2, "t2");
             
            t1.start();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t2.start();
        }
    }

    三、修改锁对象的属性

    package com.lanyun.hadoop2;
    
    /**
     * 同一对象属性的修改不会影响锁的情况
     *
     */
    public class ModifyLock {
        
        private String name ;
        private int age ;
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
        public synchronized void changeAttributte(String name, int age) {
            try {
                System.out.println("当前线程 : "  + Thread.currentThread().getName() + " 开始");
                this.setName(name);
                this.setAge(age);
                
                System.out.println("当前线程 : "  + Thread.currentThread().getName() + " 修改对象内容为: " 
                        + this.getName() + ", " + this.getAge());
                
                Thread.sleep(2000);
                System.out.println("当前线程 : "  + Thread.currentThread().getName() + " 结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) {
            final ModifyLock modifyLock = new ModifyLock();
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    modifyLock.changeAttributte("张三", 20);
                }
            },"t1");
            Thread t2 = new Thread(new Runnable() {
                public void run() {
                    modifyLock.changeAttributte("李四", 21);
                }
            },"t2");
            
            t1.start();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t2.start();
        }
    }

    四、对象锁与类所

    package com.lanyun.hadoop2;
    
    /**
     * 使用synchronized代码块加锁,比较灵活
     *
     */
    public class ObjectLock {
    
        public void method1(){
            synchronized (this) {    //对象锁
                try {
                    System.out.println("do method1..");
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        public void method2(){        //类锁
            synchronized (ObjectLock.class) {
                try {
                    System.out.println("do method2..");
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        private Object lock = new Object();
        public void method3(){        //任何对象锁
            synchronized (lock) {
                try {
                    System.out.println("do method3..");
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        
        public static void main(String[] args) {
            
            final ObjectLock objLock = new ObjectLock();
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    objLock.method1();
                }
            });
            Thread t2 = new Thread(new Runnable() {
                public void run() {
                    objLock.method2();
                }
            });
            Thread t3 = new Thread(new Runnable() {
                public void run() {
                    objLock.method3();
                }
            });
            
            t1.start();
            t2.start();
            t3.start();
        }
    }

    五、使用synchronized代码块减小锁的粒度,提高性能

    package com.lanyun.hadoop2;
    /**
     * 使用synchronized代码块减小锁的粒度,提高性能
     *
     */
    public class Optimize {
    
        public void doLongTimeTask(){
            try {
                
                System.out.println("当前线程开始:" + Thread.currentThread().getName() + 
                        ", 正在执行一个较长时间的业务操作,其内容不需要同步");
                Thread.sleep(2000);
                
                synchronized(this){
                    System.out.println("当前线程:" + Thread.currentThread().getName() + 
                        ", 执行同步代码块,对其同步变量进行操作");
                    Thread.sleep(1000);
                }
                System.out.println("当前线程结束:" + Thread.currentThread().getName() +
                        ", 执行完毕");
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) {
            final Optimize otz = new Optimize();
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    otz.doLongTimeTask();
                }
            },"t1");
            Thread t2 = new Thread(new Runnable() {
                public void run() {
                    otz.doLongTimeTask();
                }
            },"t2");
            t1.start();
            t2.start();
        }
    }

    六、避免使用字符串对象来做锁

    package com.lanyun.hadoop2;
    
    /**
     * synchronized代码块对字符串的锁,注意String常量池的缓存功能
     *
     */
    public class StringLock {
    
        public void method() {
            //new String("字符串常量")
            synchronized ("字符串常量") {
                try {
                    while(true){
                        System.out.println("当前线程 : "  + Thread.currentThread().getName() + "开始");
                        Thread.sleep(1000);        
                        System.out.println("当前线程 : "  + Thread.currentThread().getName() + "结束");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        public static void main(String[] args) {
            final StringLock stringLock = new StringLock();
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    stringLock.method();
                }
            },"t1");
            Thread t2 = new Thread(new Runnable() {
                public void run() {
                    stringLock.method();
                }
            },"t2");
            
            t1.start();
            t2.start();
        }
    }
  • 相关阅读:
    MyEclipse Servers视窗出现“Could not create the view: An unexpected exception was thrown”错误解决办法
    eclipse 安装git
    使用Maven构建Web项目
    Maven仓库构建
    JAX-WS:背后的技术JAXB及传递Map
    CXF WebService 开发文档
    eclispse 中集成多个tomcat
    Myeclipse 主题下载
    html textarea 获取换行
    jqurey click和blur执行时间冲突
  • 原文地址:https://www.cnblogs.com/dongdone/p/5711496.html
Copyright © 2020-2023  润新知