• 2.2.16锁对象的改变


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

    package com.cky.thread;
    
    /**
     * Created by edison on 2017/12/9.
     */
    public class MyServIce {
        private String lock ="123";
        public void testMethodA (){
            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();
            }
        }
    }
    package com.cky.thread;
    
    /**
     * Created by edison on 2017/12/8.
     */
    public class ThreadA extends  Thread{
        private MyServIce service;
    
        public ThreadA(MyServIce service) {
            this.service = service;
        }
    
        @Override
        public void run() {
            super.run();
            service.testMethodA();
        }
    }
    package com.cky.thread;
    
    /**
     * Created by edison on 2017/12/8.
     */
    public class ThreadB extends  Thread{
    
    
        private MyServIce service;
    
        public ThreadB(MyServIce service) {
            this.service = service;
        }
    
        @Override
        public void run() {
            super.run();
            service.testMethodA();
        }
    }
    package com.cky.thread;
    
    /**
     * Created by edison on 2017/12/9.
     */
    public class Test2 {
        public static void main(String[] args) throws InterruptedException {
            MyServIce myServIce = new MyServIce();
            ThreadA a = new ThreadA(myServIce);
            a.setName("A");
            ThreadB b= new ThreadB(myServIce);
            b.setName("B");
            a.start();
            Thread.sleep(50);
            b.start();
    
    
        }
    }

    结果分析:

    因为50毫秒过后线程B 获得的锁是456

    继续测试:

    去掉代码Thread.sleep(50)

    package com.cky.thread;
    
    /**
     * Created by edison on 2017/12/9.
     */
    public class Test2 {
        public static void main(String[] args) throws InterruptedException {
            MyServIce myServIce = new MyServIce();
            ThreadA a = new ThreadA(myServIce);
            a.setName("A");
            ThreadB b= new ThreadB(myServIce);
            b.setName("B");
            a.start();
            //Thread.sleep(50);
            b.start();
    
    
        }
    }
    Bbegin=1512803944419
    Bend=1512803946419
    Abegin=1512803946419
    Aend=1512803948419

      

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

    注意:只要对象不变,即使对象的属性被改变,运行的结果还是同步的,测试如下

    package com.cky.daemon;
    
    /**
     * Created by edison on 2017/12/9.
     */
    public class Service {
        public void methodA(UserInfo userInfo) {
            synchronized (userInfo) {
                try {
                    System.out.println("begin"+Thread.currentThread().getName());
                    userInfo.setUsrname("aaaa");
                    Thread.sleep(2000);
                    System.out.println("end"+ System.currentTimeMillis());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    package com.cky.daemon;
    
    /**
     * Created by edison on 2017/12/9.
     */
    public class UserInfo {
        private String usrname;
    
        public String getUsrname() {
            return usrname;
        }
    
        public void setUsrname(String usrname) {
            this.usrname = usrname;
        }
    }
    package com.cky.daemon;
    
    import com.cky.thread.ThreadA;
    import com.cky.thread.ThreadB;
    
    /**
     * Created by edison on 2017/12/9.
     */
    public class Test {
        public static void main(String[] args) {
            try {
                Service service = new Service();
                UserInfo userInfo = new UserInfo();
                ThreadA threadA = new ThreadA(service, userInfo);
                threadA.setName("a");
                threadA.start();
                Thread.sleep(50);
                ThreadB threadB = new ThreadB(service, userInfo);
                threadB.setName("b");
                threadB.start();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    package com.cky.thread;
    
    import com.cky.daemon.Service;
    import com.cky.daemon.UserInfo;
    
    /**
     * Created by edison on 2017/12/8.
     */
    public class ThreadA extends  Thread{
        private Service service;
        private UserInfo userInfo;
    
        public ThreadA(Service service, UserInfo userInfo) {
    
            this.service = service;
            this.userInfo = userInfo;
        }
    
        @Override
        public void run() {
            super.run();
            service.methodA(userInfo);
        }
    }
    package com.cky.thread;
    
    import com.cky.daemon.Service;
    import com.cky.daemon.UserInfo;
    
    /**
     * Created by edison on 2017/12/8.
     */
    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.methodA(userInfo);
        }
    }
    begina
    end1512804642120
    beginb
    end1512804644121
  • 相关阅读:
    安装完openfire之后打不开的解决方案
    iOS中动画的简单使用
    iOS中的多线程及GCD
    iOS 架构模式-MVVM
    iOS
    iOS 下拉刷新 上拉加载实现原理
    iOS
    iOS 中的XML解析代码(SAX)
    iOS
    iOS中的网络请求 和 网络监测
  • 原文地址:https://www.cnblogs.com/edison20161121/p/8011193.html
Copyright © 2020-2023  润新知