String常量池:
String常量池,是java为了保存字符串常量在方法区里开辟的一段空间,在执行如String str=”aa”;是会先检查常量池中有没有“aa”,如果有则直接让str指向常量池中的“aa”,如果没有则会新建一个“aa”,并且将str指向“aa”。
String和synchronized:
如果使用String作为对象锁,如果字符串相同则加锁的对象是同一个。
示例代码
class Service {
public static void print(String string) {
try {
synchronized (string) {
while(true) {
System.out.println(Thread.currentThread().getName());
Thread.sleep(1000);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ThreadA extends Thread{
private Service service;
public ThreadA(Service service) {
this.service=service;
}
@Override
public void run() {
this.service.print("AA");
}
}
class ThreadB extends Thread{
private Service service;
public ThreadB(Service service) {
this.service=service;
}
@Override
public void run() {
this.service.print("AA");
}
}
public class Main {
public static void main(String[] args) {
Service service=new Service();
ThreadA threada=new ThreadA(service);
threada.setName("A");
threada.start();
ThreadB threadb=new ThreadB(service);
threadb.setName("B");
threadb.start();
}
}
运行结果
A
A
.
.
.
A
A
A
A
结果分析
输出的结果都是A因为字符串常量都在常量池里,”AA”不管有多少在常量池里都是一个对象。所以加锁的对象是一个对象,threada一直都不会释放锁,threadb线程一直没有机会执行。