資料型別String常量池的特性
阿新 • • 發佈:2019-01-23
package com.test.Thread.StringAndSyn;
/**
* synchronized(string)同步塊與String聯合使用
* @author admin
* 2017年4月20日
*/
public class Service {
public static void print(String parm) throws InterruptedException{
synchronized (parm) {
while(true){
System.out.println("執行緒名:" +Thread.currentThread().getName());
Thread.sleep(1000);
}
}
}
public static void main(String[] args) {
Service s=new Service();
ThreadA a=new ThreadA(s);
a.setName("A");
a.start();
ThreadB b=new ThreadB(s);
b.setName("B" );
b.start();
}
}
class ThreadA extends Thread{
private Service s;
public ThreadA(Service s) {
super();
this.s = s;
}
@Override
public void run() {
try {
s.print("AAAA");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ThreadB extends Thread{
private Service s;
public ThreadB(Service s) {
super();
this.s = s;
}
@Override
public void run() {
try {
s.print("AAAA");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
執行結果:
出現這樣的情況是因為String傳入的兩個值都是AAAA,兩個執行緒只有相同的資源所以造成執行緒B不能執行。這就是String常量池所帶來的問題,因此大多數情況下,同步的synchronized程式碼塊都不使用String作為鎖物件 比如new Object()例項化一個object物件,但它並不放入快取中
修改程式碼如下 會出現交替列印
package com.test.Thread.StringAndSyn;
/**
* 交替列印的原因是持有鎖不是同一個
* @author admin
* 2017年4月20日
*/
public class Service2 {
public static void print(Object object) throws InterruptedException{
synchronized (object) {
while(true){
System.out.println("執行緒名:"+Thread.currentThread().getName());
Thread.sleep(1000);
}
}
}
public static void main(String[] args) {
Service2 s=new Service2();
ThreadAA a=new ThreadAA(s);
a.setName("A");
a.start();
ThreadBB b=new ThreadBB(s);
b.setName("B");
b.start();
}
}
class ThreadAA extends Thread{
private Service2 s;
public ThreadAA(Service2 s) {
super();
this.s = s;
}
@Override
public void run() {
try {
s.print("AAAA");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ThreadBB extends Thread{
private Service2 s;
public ThreadBB(Service2 s) {
super();
this.s = s;
}
@Override
public void run() {
try {
s.print("AAAA");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}