多线程同步问题-练习题3-笔记整理

练习题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);
		}
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值