2.4String的常量池(String池)特性

看一段伪代码

String a = "a";
String b = "a";
String c = new String("a");
System.out.println(a==b);//true
System.out.println(a==c);//false

因为java的String类型会有一个常量池管理String对象,当出现的String对象在String池中不存在时即在String池中创建该对象,a和b都指向了同一个地址。而new则会分配一个新的地址然后复制常量池的内容,若内容不存在,常量池创建完再复制,虽然内容一样可是c和a(b)指向的地址已经不一样了。

package com.myObject;

public class Object1 {

    public void print(String str) {
        try {
            synchronized (str) {
                while (true) {
                    System.out.println(System.currentTimeMillis() + " "+ Thread.currentThread().getName());
                    Thread.sleep(1000);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
package com.myThread;

import com.myObject.Object1;

public class Thread1a extends Thread {
    Object1 object1;

    public Thread1a(Object1 object1) {
        this.object1 = object1;
    }

    @Override
    public void run() {
        super.run();

        object1.print("A");

    }
}
package com.myThread;

import com.myObject.Object1;

public class Thread1b extends Thread {
    Object1 object1;

    public Thread1b(Object1 object1) {
        this.object1 = object1;
    }

    @Override
    public void run() {
        super.run();

        object1.print("A");

    }
}
package com.myThread;

import com.myObject.Object1;

public class Thread1c extends Thread {
    Object1 object1;
    String c;
    public Thread1c(Object1 object1,String str) {
        this.object1 = object1;
        this.c=str;
    }

    @Override
    public void run() {
        super.run();
        object1.print(c);

    }
}

package com.myThread;

import com.myObject.Object1;

public class Thread1d extends Thread {
    Object1 object1;
    String d=new String ("A");
    public Thread1d(Object1 object1,String str) {
        this.object1 = object1;
        this.d = str;
    }

    @Override
    public void run() {
        super.run();
        object1.print(d);

    }
}
package com.test;

import com.myObject.Object1;
import com.myThread.Thread1a;
import com.myThread.Thread1b;
import com.myThread.Thread1c;

public class Test1 {
    public static void main(String[] args) throws InterruptedException {


        Object1 object1 = new Object1();
        String str = new String ("A");
        Thread1a thread1a = new Thread1a(object1);
        thread1a.setName("a");
        thread1a.start();
        Thread1b thread1b = new Thread1b(object1);
        thread1b.setName("b");
        thread1b.start();
        Thread1c thread1c = new Thread1c(object1,str);
        thread1c.setName("c");
        thread1c.start();
        Thread1d thread1d = new Thread1d(object1,str);
        thread1d.setName("d");
        thread1d.start();

    }
}
操作run结果分析
注释ThreadC和DA:object1.print(“A”);
B:object1.print(“A”);
同步,B被阻塞“A”,在Java中的内存地址一样
注释ThreadC和DA:object1.print(“A”);
B:object1.print(“B”);
异步
注释ThreadB和DA:object1.print(“A”);
C:object1.print(c);
异步“A”和new(“A”)在Java中的内存地址不一样
注释ThreadA和BC:object1.print(c);
D:object1.print(d);
同步c和d都是指向new(“A”)在Java中的内存地址一样,同一个对象
ThreadC和D的c和d分别由自己newC:object1.print(c);
D:object1.print(d);
异步c和d指向的new(“A”)在Java中的内存地址不一样



总结
一般情况下,synchronized同步代码块是不会用String作为锁对象,因为String池的存在,直接使用(“a”“b”等非new的String对象)很容易造成多个线程抢夺同一个String资源,可以改用Object对象,因为通常都不会用new String()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值