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

    科技2022-07-12  116

    文章目录

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

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

    字符串对象的改变

    任务代码 /** * Created with IntelliJ IDEA. * Description: If you don't work hard, you will a loser. * User: Listen-Y. * Date: 2020-10-03 * Time: 21:17 */ 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()); } } } 线程类和启动类 /** * Created with IntelliJ IDEA. * Description: If you don't work hard, you will a loser. * User: Listen-Y. * Date: 2020-10-03 * Time: 21:21 */ 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()); } } } 启动类 /** * Created with IntelliJ IDEA. * Description: If you don't work hard, you will a loser. * User: Listen-Y. * Date: 2020-10-03 * Time: 21:50 */ 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(); } } 运行结果 这个代码我们发现, 只要对象不变, 即使属性被改变, 运行的结果还是同步的
    Processed: 0.008, SQL: 8