String常量池特性与同步相关的问题与解决方案——T2217

package 对象及变量的并发访问2;

/**
 *  String常量池特性与同步相关的问题与解决方案
 *    JVM中String常量池
 *
 *    class test{
 *        public print(){
 *            String a="a";
 *            String b="a";
 *            sout(a==b);
 *        }
 *    }
 *
 *    结果为true;
 *
 *  但将synchronized(string)同步块与String联合使用时,要注意常量池会带来的意外。
 *
 *  结果: 因为String的两个值都是“AA”,两个线程持有相同的锁,造成B线程不能执行。这就是
 *String常量池带来的问题,所以大多数情况下,同步synchronized代码块不使用String作为锁对象
 *而是改用其他的。如new Object()实例化一个新的Object对象,它并不放入缓存池中,或者执行
 *new String()创建不同的字符串对象,形成不同锁。
 */

class ServiceT2217{
    public static void print(String stringParm){
        try {
            synchronized (stringParm){
                while (true){
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Service2T2217{
    public static void print(Object object){
        try {
            synchronized (object){
                while (true){
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(3000);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class MyThreadAT2217 extends Thread{
    private ServiceT2217 serviceT2217;

    public MyThreadAT2217(ServiceT2217 serviceT2217){
        super();
        this.serviceT2217=serviceT2217;
    }

    @Override
    public void run() {
        ServiceT2217.print("AA");
    }
}

class MyThreadA2T2217 extends Thread{
    private Service2T2217 service2T2217;

    public MyThreadA2T2217 (Service2T2217 service2T2217){
        super();
        this.service2T2217=service2T2217;
    }

    @Override
    public void run() {
        Service2T2217.print(new Object());
    }
}

class MyThreadBT2217 extends Thread{
    private ServiceT2217 serviceT2217;

    public MyThreadBT2217(ServiceT2217 serviceT2217){
        super();
        this.serviceT2217=serviceT2217;
    }

    @Override
    public void run() {
        ServiceT2217.print("AA");
    }
}

class MyThreadB2T2217 extends Thread{
    private Service2T2217 service2T2217;

    public MyThreadB2T2217(Service2T2217 service2T2217){
        super();
        this.service2T2217=service2T2217;
    }

    @Override
    public void run() {
        Service2T2217.print(new Object());
    }
}
class RunT2217{
    public RunT2217(){
        ServiceT2217 serviceT2217=new ServiceT2217();

        MyThreadAT2217 at2217=new MyThreadAT2217(serviceT2217);
        at2217.setName("A");
        at2217.start();

        MyThreadBT2217 bt2217=new MyThreadBT2217(serviceT2217);
        bt2217.setName("B");
        bt2217.start();
    }

}

class Run2T2217{
    public Run2T2217(){
        Service2T2217 service2T2217=new Service2T2217();

        MyThreadA2T2217 a2T2217=new MyThreadA2T2217(service2T2217);
        a2T2217.setName("A2");
        a2T2217.start();

        MyThreadB2T2217 b2T2217=new MyThreadB2T2217(service2T2217);
        b2T2217.setName("B2");
        b2T2217.start();
    }
}
public class T2217 {
    public static void main(String[] args) {
        //RunT2217 runT2217=new RunT2217();

        Run2T2217 run2T2217=new Run2T2217();
    }
}

RunT2217 runT2217=new RunT2217();在这里插入图片描述
Run2T2217 run2T2217=new Run2T2217();在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值