博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
奇葩锁
阅读量:4973 次
发布时间:2019-06-12

本文共 8455 字,大约阅读时间需要 28 分钟。

一、改变了锁对象

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

 

转载于:https://www.cnblogs.com/dongdone/p/5711496.html

你可能感兴趣的文章
笔记:git基本操作
查看>>
生成php所需要的APNS Service pem证书的步骤
查看>>
JavaWeb之JSON
查看>>
HOT SUMMER 每天都是不一样,积极的去感受生活 C#关闭IE相应的窗口 .
查看>>
windows平台上编译mongdb-cxx-driver
查看>>
optionMenu-普通菜单使用
查看>>
2016-2017-2点集拓扑作业[本科生上课时]讲解视频
查看>>
GNU/Linux超级本ZaReason Ultralap 440体验
查看>>
将github上托管的代码 在我的域名下运行
查看>>
【Manthan, Codefest 18 (rated, Div. 1 + Div. 2) C】Equalize
查看>>
【codeforces 767A】Snacktower
查看>>
【MemSQL Start[c]UP 3.0 - Round 1 C】 Pie Rules
查看>>
Ognl中“%”、“#”、“$”详解
查看>>
我对应用软件——美团的看法
查看>>
执行了的程序,才是你的程序.
查看>>
struts2.x + Tiles2.x读取多个xml 配置文件
查看>>
表单校验之datatype
查看>>
python第六篇文件处理类型
查看>>
ubuntu16系统磁盘空间/dev/vda1占用满的问题
查看>>
grid网格布局
查看>>