练习题3:
程序同时启用了4个线程去调用TestDo.doSome()方法,由于TestDo.doSome方法内部的代码是先暂停1秒,
然后在输出以秒为单位的当前时间值,所以,会打印出4个相同的时间值,如下所示:
4:4:1258199615
1:1:1258199615
3:3:1258199615
1:1:1258199615
修改代码,如果有几个线程调用TestDo.doSome方法时,传递进去的key相等,则这几个线程应互斥排队输出结果,
即当有有个线程的key都是“1”时,他们中的一个要比其他线程晚1秒输出结果。
提示:对key相同的线程处理时,使用同一把锁,阻塞
题目代码示例:
public class Test3 extends Thread{
private TestDo1 testDo;
private String key;
private String value;
public Test3(String key1,String key2, String value) {
this.testDo = TestDo1.getInstance();
this.key = key1+key2;
this.value = value;
}
public static void main(String[] args) {
Test3 a=new Test3("1","","1");
Test3 b=new Test3("2","","2");
Test3 c=new Test3("3","","3");
Test3 d=new Test3("4","","4");
System.out.println("begin:"+System.currentTimeMillis()/1000);
a.start();
b.start();
c.start();
d.start();
}
public void run(){
testDo.doSome(key, value);
}
}
class TestDo1{
private TestDo1(){}
private static TestDo1 _instance=null;
public static TestDo1 getInstance(){
if(_instance==null){
synchronized (TestDo1.class) {
if(_instance==null){
_instance=new TestDo1();
}
}
}
return _instance;
}
public static void doSome(Object key,String value){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(key+":"+value+":"+System.currentTimeMillis()/1000);
}
}
修改后代码示例:
public class Test3_1 extends Thread{
private TestDo1 testDo;
private String key;
private String value;
public Test3_1(String key1,String key2, String value) {
this.testDo = TestDo1.getInstance();
this.key = key1+key2;
this.value = value;
}
public static void main(String[] args) {
Test3_1 a=new Test3_1("1","","1");
Test3_1 b=new Test3_1("2","","2");
Test3_1 c=new Test3_1("3","","3");
Test3_1 d=new Test3_1("1","","1");
System.out.println("begin:"+System.currentTimeMillis()/1000);
a.start();
b.start();
c.start();
d.start();
}
public void run(){
testDo.doSome(key, value);
}
}
class TestDo1{
private TestDo1(){}
private static TestDo1 _instance=null;
public static TestDo1 getInstance(){
if(_instance==null){
synchronized (TestDo1.class) {
if(_instance==null){
_instance=new TestDo1();
}
}
}
return _instance;
}
ArrayList<String> list=new ArrayList<String>();
public void doSome(Object key,String value){
String str=(String)key; //关键点,维护key相同,使用相同的锁阻塞
if(list.contains(key)){
Iterator iterator = list.iterator();
while(iterator.hasNext()){
String tmp = (String)iterator.next();
if(tmp.equals(key)){
str=tmp;
}
}
}else{
list.add((String)key);
}
synchronized (str) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(key+":"+value+":"+System.currentTimeMillis()/1000);
}
}
}