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