多线程 锁对象改变

时间:2021-11-22 13:05:48
在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,
则这些线程之间就是同步的;如果分别获得锁对象,这些线程直接就是异步的
1. 数值型数据
    直接看例子,然后再解释:
    public class MyService {
    private String lock="123";
    public void testMethod(){
        try {
            synchronized (lock){
                System.out.println(Thread.currentThread().getName()+" begin "+System.currentTimeMillis());
                Thread.sleep(50);
                lock="456";
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName()+" end "+System.currentTimeMillis());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


public class ThreadA extends Thread{
    private MyService myService;
    public ThreadA(MyService myService){
        super();
        this.myService=myService;
    }


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


    * 情况1:
    public class Run1 {
    public static void main(String[] args) throws InterruptedException{
        MyService service=new MyService();
        ThreadA a=new ThreadA(service);
        a.setName("A");
        ThreadA b=new ThreadA(service);
        b.setName("B");
        a.start();
        Thread.sleep(100);
        b.start();
    }
}
        结果:
        A begin 1503113512171
        B begin 1503113512275
        A end 1503113514223
        B end 1503113514341


    *情况2:
    public class Run1 {
    public static void main(String[] args) throws InterruptedException{
        MyService service=new MyService();
        ThreadA a=new ThreadA(service);
        a.setName("A");
        ThreadA b=new ThreadA(service);
        b.setName("B");
        a.start();
        b.start();
    }
}
        结果:
        B begin 1503113404726
        B end 1503113406794
        A begin 1503113406794
        A end 1503113408846
    * 总结一下,如果线程已经在等待锁,如上面的B线程,那么该锁就不会再变化了,即使该对象本身确实发生了变化,
        如果还没有加锁或者等待锁,则可以变化。
2. 引用型数据
    只要对象不变,已经对象的属性被改变,运行的结果还是同步
    eg:
    public class Userinfo {
    private String Username;
    private String sex;


    public String getUsername() {
        return Username;
    }


    public void setUsername(String username) {
        Username = username;
    }


    public String getSex() {
        return sex;
    }


    public void setSex(String sex) {
        this.sex = sex;
    }
}
    public class Service {
    public void serviceMethodA(Userinfo userinfo){
        synchronized (userinfo){
            try {
                System.out.println(Thread.currentThread().getName());
                userinfo.setUsername("abcabsdfdf");
                Thread.sleep(3000);
                System.out.println("end! time="+System.currentTimeMillis());
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}
    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() {
        service.serviceMethodA(userinfo);
    }
}
    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);
            ThreadA b=new ThreadA(service,userinfo);
            b.setName("b");
            b.start();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
    结果:
    a
    end! time=1503114681655 
    b
    end! time=1503114684664