Java~常见的俩个锁对象改变的问题 (字符串对象的改变和对象属性的改变)

   日期:2020-10-05     浏览:102    评论:0    
核心提示:文章目录字符串对象的改变对象属性的改变注意一个问题如果多个线程同时持有锁对象, 且同时持有的是相同的锁对象, 那么这些线程之间的任务就是同步的, 如果分别持有不同的锁对象, 那么就是异步的.字符串对象的改变任务代码/** * Created with IntelliJ IDEA. * Description: If you don't work hard, you will a loser. * User: Listen-Y. * Date: 2020-10-03 * Time:

文章目录

    • 字符串对象的改变
    • 对象属性的改变

  • 注意一个问题如果多个线程同时持有锁对象, 且同时持有的是相同的锁对象, 那么这些线程之间的任务就是同步的, 如果分别持有不同的锁对象, 那么就是异步的.

字符串对象的改变

  • 任务代码

public class MyService { 

    private  String lock = "123";

    public void testMethod() { 

        synchronized (lock) { 
            System.out.println(Thread.currentThread().getName() + " begin at: "
                    + System.currentTimeMillis());
            lock = "456";

            try { 
                Thread.sleep(2000);
            } catch (InterruptedException e) { 
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + " end at: "
                    + System.currentTimeMillis());

        }

    }
}

  • 线程类和启动类

public class Run2 { 


    public static void main(String[] args) throws InterruptedException { 
        MyService service = new MyService();
        Thread t1 = new Thread("A") { 
            @Override
            public void run() { 
                service.testMethod();
            }
        };
        Thread t2 = new Thread("B") { 
            @Override
            public void run() { 
                service.testMethod();
            }
        };
        t1.start();
        //关键点 这里等待0.1秒, A线程等待2秒
        Thread.sleep(100);
        t2.start();
    }
}

  • 运行结果
  • 此时我们发现A和B俩个线程是A获得锁进入之后过了100秒后B也获得锁进入了, 但是此时A并没有出去, 也就是A并没有释放锁, 究其原因就是A进入之后再0.1秒内修改了lock这个对象, 要知道字符串类型"123"和"456"是俩个不同的类型, 所以才会有这样的现象, 如果我们不让等待那0.1秒, 就不会出现这样的问题
  • 注释掉后就不会有这样的问题
  • 此时A和B差不多是同时要求启动, 俩个线程之间一开始竞争的还是"123"这把锁, 虽然将锁改成"456" , 但结果还是异步的, 因为共同争抢的锁是"123"

对象属性的改变

  • user类
public class User { 

    public String name;
    public int age;

    public User(String name, int age) { 
        this.name = name;
        this.age = age;
    }

}
  • 服务类
public class Service { 

    public void testMethod(User user) { 
        synchronized (user) { 
            System.out.println(Thread.currentThread().getName() + " begin: " +
                    System.currentTimeMillis());
            //修改信息
            user.age = 99;
            user.name = "HaHa";
            try { 
                Thread.sleep(3000);
            } catch (InterruptedException e) { 
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + " end: " +
                    System.currentTimeMillis());
        }
    }

}
  • 启动类

public class Run3 { 

    public static void main(String[] args) throws InterruptedException { 
        User user = new User("listen", 20);
        Service service = new Service();

        Thread t1 = new Thread("A") { 
            @Override
            public void run() { 
                service.testMethod(user);
            }
        };
        Thread t2 = new Thread("B") { 
            @Override
            public void run() { 
                service.testMethod(user);
            }
        };
        t1.start();
        //关键点
        Thread.sleep(100);
        t2.start();
    }
}

  • 运行结果
  • 这个代码我们发现, 只要对象不变, 即使属性被改变, 运行的结果还是同步的
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服