Java多线程(四) synchronized(非this对象)同步语句块

1. 将任意对象作为对象的监视器

1.1 在多个线程持有“对象监视器”为同一对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象)同步代码块的代码。

1.1.1 Service

public class Service {
    private String userName;
    private String password;
    private String aString = new String();

    public void setUserInfo(String userName, String password){

        try {
            synchronized (aString){
                System.out.println(Thread.currentThread().getName() + " in block");

                this.userName = userName;
                Thread.sleep(1000);
                this.password = password;

                System.out.println(Thread.currentThread().getName() + " out block");
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

1.1.2 ThreadA

public class ThreadA extends Thread {
    private Service service;

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

    @Override
    public void run(){
        service.setUserInfo("a", "aa");
    }
}

1.1.3 ThreadB

public class ThreadB extends Thread {
    private Service service;

    public ThreadB(Service service){
        super();
        this.service = service;
    }

    @Override
    public void run(){
        service.setUserInfo("b", "bb");
    }
}

1.1.4 Test

public class Test {
    public static void main(String[] args) {
    	//A和B共用一个service这个对象,如果不共用一个service,会异步执行
        Service service = new Service();

        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();
    }
}

1.1.5 运行结果

A in block
A out block
B in block
B out block

1.2 验证如果多个线程持有“对象监视器”不是同一对象,synchronized(非this对象)同步代码块将异步执行

1.2.1 修改Service类

public class Service {
    private String userName;
    private String password;

    public void setUserInfo(String userName, String password){
        try {
        	//aString是定义在setUsrInfo方法内的
            String aString = new String();

            synchronized (aString){
                System.out.println(Thread.currentThread().getName() + " in block");

                this.userName = userName;
                Thread.sleep(1000);
                this.password = password;

                System.out.println(Thread.currentThread().getName() + " out block");
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

1.2.2 运行结果

其他类不变,结果如下

A in block
B in block
A out block
B out block

1.3验证synchronized(非this对象)块与synchronized方法是异步执行

1.3.1 修改Service类

public class Service {
    private String userName;
    private String password;
    private String aString = new String();

    public void setUserInfo(String userName, String password){

        try {
            synchronized (aString){
                System.out.println(Thread.currentThread().getName() + " in block");

                this.userName = userName;
                Thread.sleep(1000);
                this.password = password;

                System.out.println(Thread.currentThread().getName() + " out block");
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

	//与上面的synchronized (aString)是异步的
    synchronized public void synchronizedMethod(){
        System.out.println("synchronizedMethod begin");
        System.out.println("synchronizedMethod end");
    }
}

1.3.2 修改ThreadB类

public class ThreadB extends Thread {
    private Service service;

    public ThreadB(Service service){
        super();
        this.service = service;
    }

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

1.3.3 运行结果

A in block
synchronizedMethod begin
synchronizedMethod end
A out block

从结果看是异步执行的

1.4 验证synchronized(a)和synchronized(b)是异步执行

1.4.1 修改Service 类

public class Service {
    private String aString = new String();
    private String bString = new String();

    public void methodA() {
        try {
            synchronized (aString) {
                System.out.println(Thread.currentThread().getName() + " in aString block");
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + " out aString block");
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void methodB() {
    	//和上面的synchronized (aString)是异步执行的
        synchronized (bString) {
            System.out.println(Thread.currentThread().getName() + " in bString block");
            System.out.println(Thread.currentThread().getName() + " out bString block");
        }
    }
}

1.4.2 ThreadA

public class ThreadA extends Thread {
    private Service service;

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

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

1.4.3 ThreadB

public class ThreadB extends Thread {
    private Service service;

    public ThreadB(Service service){
        super();
        this.service = service;
    }

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

1.4.4 Test

public class Test {
    public static void main(String[] args) {
        Service service = new Service();

        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();
    }
}

1.4.5 运行结果

A in aString block
B in bString block
B out bString block
A out aString block

2. 数据类型String的常量池特性

2.1 synchronized代码块不要使用String作为锁对象

在JVM中具有String常量池缓存功能,如下代码返回为true。

public class StringTest {
    public static void main(String[] args) {
        String a = "a";
        String b = "a";
        //打印true
        System.out.println(a == b);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑟王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值