zoukankan      html  css  js  c++  java
  • Synchronized 锁的错误使用方式及如何解决

    synchronized关键字,一般称之为”同步锁“,用它来修饰需要同步的方法和需要同步代码块,默认是当前对象作为锁的对象。

    同步锁锁的是同一个对象,如果对象发生改变,则锁会不生效。

    锁失败的代码:

    public class IntegerSynTest {
    
        //线程实现Runnable接口
        private static class Worker implements Runnable{
    
            private Integer num;
    
            public Worker(Integer num){
                this.num=num;
            }
            @Override
            public void run() {
                
                synchronized (num){
                    Thread thread = Thread.currentThread();
                    //System.identityHashCode:返回原生的hashCode值,不管Object对象是被重写;空引用的哈希代码为零
                    System.out.println(thread.getName()+"--@:---"+System.identityHashCode(num));
                    num++;
                    System.out.println(thread.getName()+"------num:"+num+"---"+System.identityHashCode(num));
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(thread.getName()+"------num:"+num+"---"+System.identityHashCode(num));
                }
            }
    
            public static void main(String[] args) {
                Worker worker = new Worker(1);
                for (int i = 0; i < 5; i++) {
                    new Thread(worker).start();
                }
            }
        }
    }

    锁失败的运行结果:

    锁失败的原因:

    1.num++  的  .class  实现是这样的  Integer integer1 = this.num, integer2 = this.num = Integer.valueOf(this.num.intValue() + 1);

    2. 查看 Integer.valueOf() 的源代码

     这时发现,它是重新 new 出一个新的 Integer,这样的话,每 ++ 一次,那么就会产生一个新的对象,而Synchronize锁是锁同一个对象,当锁不同对象时,则会锁失败。

    解决方法:

    Synchronized 同步锁只要锁的对象不发生改变即可,那么由此只需要声明一个对象,不修改它,锁这一个对象即可(还有其他方法暂不一一列举,以后也不会列举了)。

    锁成功的代码

    public class IntegerSynTest {
    
        //线程实现Runnable接口
        private static class Worker implements Runnable{
    
            private Integer num;
            /**
             *  ---重点看这里---
             *  声明要锁的对象
             *  ---重点看这里---
             */
            private Object object = new Object();
    
            public Worker(Integer num){
                this.num=num;
            }
            @Override
            public void run() {
                //修改锁对象
                synchronized (num){
                    Thread thread = Thread.currentThread();
                    //System.identityHashCode:返回原生的hashCode值,不管Object对象是被重写;空引用的哈希代码为零
                    System.out.println(thread.getName()+"--@:---"+System.identityHashCode(num));
                    num++;
                    System.out.println(thread.getName()+"------num:"+num+"---"+System.identityHashCode(num));
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(thread.getName()+"------num:"+num+"---"+System.identityHashCode(num));
                }
            }
    
            public static void main(String[] args) {
                Worker worker = new Worker(1);
                for (int i = 0; i < 5; i++) {
                    new Thread(worker).start();
                }
            }
        }
    }

    锁成功的运行结果:

  • 相关阅读:
    Kafka学习笔记之kafka高版本Client连接0.9Server引发的血案排查
    机器学习笔记之python实现朴素贝叶斯算法样例
    机器学习笔记之python实现支持向量机SVM算法样例
    机器学习笔记之AdaBoost算法详解以及代码实现
    机器学习笔记之python实现关联规则算法Apriori样例
    机器学习笔记之python实现AdaBoost算法
    F-47(copy 邓大顾)
    js 设置标题 空白
    微信授权验证
    iphone web 时间 问题
  • 原文地址:https://www.cnblogs.com/mjtabu/p/12702721.html
Copyright © 2011-2022 走看看