美文网首页
2.2.16锁对象的改变

2.2.16锁对象的改变

作者: 农家男孩 | 来源:发表于2017-07-23 13:40 被阅读0次

在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间就是同步的;如果分别获得锁对象,这些线程之间就是异步的。

/**
 * @author wuyoushan
 * @date 2017/4/19.
 */
public class MyService {
    private String lock="123";

    public void testMethod(){
        try {
            synchronized (lock) {
                System.out.println(Thread.currentThread().getName() + " begin " +
                        System.currentTimeMillis());
                lock = "456";
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + " end " +
                        System.currentTimeMillis());
            }
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadA extends Thread{

    private MyService service;

    public ThreadA(MyService service) {
        this.service = service;
    }

    @Override
    public void run() {
       super.run();
        service.testMethod();
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadB extends Thread{

   private MyService service;

    public ThreadB(MyService service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.testMethod();
    }
}

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args) throws InterruptedException {
        MyService service=new MyService();
        ThreadA a=new ThreadA(service);
        a.setName("A");
        ThreadB b=new ThreadB(service);
        b.setName("B");
        a.start();
        Thread.sleep(50);
        b.start();
    }
}

程序运行后的结果为:

A begin 1493684592096
B begin 1493684592146
A end 1493684594096
B end 1493684594146

程序的结果是异步输出的。因为50毫秒过后B取得的锁是“456”

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args) throws InterruptedException {
        MyService service=new MyService();
        ThreadA a=new ThreadA(service);
        a.setName("A");
        ThreadB b=new ThreadB(service);
        b.setName("B");
        a.start();
//        Thread.sleep(50);
        b.start();
    }
}

去掉Thread.sleep(50),程序的运行结果如下:

A begin 1493685002103
A end 1493685004104
B begin 1493685004104
B end 1493685006104

线程A和B持有的锁都是“123”,虽然将锁改成了“456”,但是结果还是同步的,因为A和B共同争抢的锁是“123”。

还需要提示一下,只要对象不变,即使对象的属性被改变,运行的结果还是同步。

/**
 * @author wuyoushan
 * @date 2017/4/10.
 */
public class Service {
   public void serviceMethodA(UserInfo userInfo){
        synchronized (userInfo){
            try {
                System.out.println(Thread.currentThread().getName());
                userInfo.setUserName("abcabcabc");
                Thread.sleep(3000);
                System.out.println("end! time="+System.currentTimeMillis());
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
   }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadA extends Thread{

    private Service service;
    private UserInfo userInfo;

    public ThreadA(Service service,UserInfo userInfo) {
        super();
        this.service = service;
        this.userInfo=userInfo;
    }

    @Override
    public void run() {
       super.run();
       service.serviceMethodA(userInfo);
    }
}

/**
 * @author wuyoushan
 * @date 2017/4/4.
 */
public class ThreadB extends Thread{

    private Service service;
    private UserInfo userInfo;

    public ThreadB(Service service,UserInfo userInfo) {
        this.service = service;
        this.userInfo=userInfo;
    }

    @Override
    public void run() {
        super.run();
        service.serviceMethodA(userInfo);
    }
}

/**
 * @author wuyoushan
 * @date 2017/3/20.
 */
public class Run {
    public static void main(String[] args){
        try {
            Service service = new Service();
            UserInfo userInfo = new UserInfo();
            ThreadA a = new ThreadA(service, userInfo);
            a.setName("a");
            a.start();
            Thread.sleep(50);

            ThreadB b = new ThreadB(service, userInfo);
            b.setName("b");
            b.start();
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }
}

程序的运行结果为:

a
end! time=1493685934399
b
end! time=1493685937399

摘选自 java多线程核心编程技术-2.2.16

相关文章

  • 2.2.16锁对象的改变

    在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间...

  • tfs

    2.2.16 2.6.4

  • 锁对象的改变

    在前面学习完多线程的synchronized对象锁之后,不禁思考到,如果当某一线程获得某对象的对象锁后,在其内部锁...

  • 锁对象改变引发的线程问题

    Java多线程锁对象的改变 用lock获取锁对象,当lock被修改以后,会产生是一把新的锁,另一个线程获取锁对象时...

  • synchronized的锁对象改变问题

    大家都知道synchronized是一个对象锁,所以当对象变化时,锁就会消失,就会没有同步效果。 请看下面的问题:...

  • 乐观锁悲观锁

    乐观锁悲观锁: 悲观 :每次在拿数据的时候都会上锁。开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之...

  • 2022-10-27 P56-60

    2.2.16顽固不化如果分析有效,应该会对病人产生影响,病人的行为应该会有所改变。如果察觉不到阻抗的线索,那么我们...

  • synchronized笔记

    从被锁对象的性质上来说,synchronized加的锁分两种:实例对象锁和class对象锁。实例对象锁 这两种方式...

  • synchronized和lock简单理解

    synchronized(同步锁) 思考:锁什么?锁对象 可能锁对象包括:this,临界资源对象(所有线程可能访问...

  • synchronized 修饰静态方法、普通方法与代码块的区别

    概念: 类锁:所有对象共用一个锁 对象锁:一个对象一把锁,多个对象多把锁。 一、synchronized修饰普通方...

网友评论

      本文标题:2.2.16锁对象的改变

      本文链接:https://www.haomeiwen.com/subject/yccmkxtx.html