在JVM中有string常量池缓存的功能。
package com.leran.thread.demo1;
public class Test {
public static void main(String[] args) { String a = "a"; String b = "a"; System.out.println(a == b); }}
结果:true;
for example:
public class Service {
public static void print(String stringParam) { try { synchronized (stringParam) { while (true) { System.out.println(Thread.currentThread().getName()); Thread.sleep(1000); } }
} catch (Exception e) {
e.printStackTrace(); }
}
}
package com.leran.thread.demo1;
public class ThreadA extends Thread {
private Service service; public ThreadA(Service service){ super(); this.service=service; } @Override public void run() { service.print("AA"); }}
package com.leran.thread.demo1;
public class ThreadB extends Thread {
private Service service; public ThreadB(Service service){ super(); this.service=service; } @Override public void run() { service.print("AA"); }}
package com.leran.thread.demo1;
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("A"); b.start(); }}
输出结果是: A A A A A.....
出现这样的结果就是因为String的两个值都是AA,两个线程持有相同的锁,所以造成线程B不能执行。这就是String常量池所带来的问题。因此
在大多数情况下,同步synchronized代码块都不使用String作为锁对象,而改用其他,比如new Object()实例化Object对象,但它不放入缓存池中。