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();