JAVA几个线程互斥排队输出结果
2014-12-07 10:22
141 查看
现有程序同时启动了4个线程去掉用TestDo.doSome(key,value)方法,由于TestDo.doSome(key,value)方法内的代码是先暂停1秒,然后再输出以秒为单位的当前时间值,所以,会打印4个相同的时间值,如下所示:
begin1417917472
3:3:1417917473
1:1:1417917473
4:4:1417917473
1:2:1417917473
请修改代码,如果有几个线程调用TestDo.doSome(key,value)方法时,传递进去的key相等(equals比较为true),则这几个线程应互斥排队输出结果,即当有两个线程的key都是”1”时,他们中的一个要比灵位其他线程晚一秒输出结果,如下所示:
begin1417917541
3:3:1417917542
1:1:1417917542
4:4:1417917542
1:2:1417917543
原来代码:
答案代码:
begin1417917472
3:3:1417917473
1:1:1417917473
4:4:1417917473
1:2:1417917473
请修改代码,如果有几个线程调用TestDo.doSome(key,value)方法时,传递进去的key相等(equals比较为true),则这几个线程应互斥排队输出结果,即当有两个线程的key都是”1”时,他们中的一个要比灵位其他线程晚一秒输出结果,如下所示:
begin1417917541
3:3:1417917542
1:1:1417917542
4:4:1417917542
1:2:1417917543
原来代码:
package cn.sync; public class Test3 extends Thread{ private TestDo testDo; private String key; private String value; public Test3(String key, String key2, String value) { this.testDo = TestDo.getInstance(); /* 常量"1"和"1"是同一个对象,下面这行代码是要用"1"+""的方式产生新对象 以实现内容没有改变,仍然相等(都还为"1"),但对象queue不再是同一个对象 */ this.key = key + key2; this.value = value; } public static void main(String[] args) { // TODO Auto-generated method stub Test3 a = new Test3("1","","1"); Test3 b = new Test3("1","","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() { // TODO Auto-generated method stub testDo.doSome(key, value); } } class TestDo{ private TestDo(){} private static TestDo _instance = new TestDo(); public static TestDo getInstance(){ return _instance; } public void doSome(Object key,String value){ //以大括号内的是需要局部同步的代码,不能改动 { try { Thread.sleep(1000); System.out.println(key+":"+value+":" +(System.currentTimeMillis()/1000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
答案代码:
package cn.sync; import java.util.Iterator; import java.util.concurrent.CopyOnWriteArrayList; public class AnswerTest3 extends Thread{ private TestDo testDo; private String key; private String value; public AnswerTest3(String key, String key2, String value) { this.testDo = TestDo.getInstance(); /* 常量"1"和"1"是同一个对象,下面这行代码是要用"1"+""的方式产生新对象 以实现内容没有改变,仍然相等(都还为"1"),但对象queue不再是同一个对象 */ this.key = key + key2; this.value = value; } public static void main(String[] args) { // TODO Auto-generated method stub AnswerTest3 a = new AnswerTest3("1","","1"); AnswerTest3 b = new AnswerTest3("1","","2"); AnswerTest3 c = new AnswerTest3("3","","3"); AnswerTest3 d = new AnswerTest3("4","","4"); System.out.println("begin" + (System.currentTimeMillis()/1000)); a.start(); b.start(); c.start(); d.start(); } public void run() { // TODO Auto-generated method stub testDo.doSome(key, value); } } class TestDo{ private TestDo(){} private static TestDo _instance = new TestDo(); public static TestDo getInstance(){ return _instance; } //private ArrayList keys = new ArrayList(); /* * 用ArrayList会出现两个结果和一个错误 * begin1417917694 * 结果1 3:3:1417917695 1:1:1417917695 4:4:1417917695 1:2:1417917696 结果2 begin1417917815 3:3:1417917816 1:2:1417917816 1:1:1417917816 4:4:1417917816 ERROR 不能在遍历ArrayList的时候,对ArrayList进行添加或者删除 换用CopyOnWriteArrayList 发现还是会出现两个结果,结果如上所示。不明白了??? * */ CopyOnWriteArrayList keys = new CopyOnWriteArrayList(); public void doSome(Object key,String value){ Object o = key; if(!keys.contains(o)){ keys.add(o); }else{ for(Iterator iter=keys.iterator();iter.hasNext();){ try { Thread.sleep(20); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Object oo = iter.next(); if(oo.equals(o)){ o = oo; break; } } } //以大括号内的是需要局部同步的代码,不能改动 synchronized(o) { try { Thread.sleep(1000); System.out.println(key+":"+value+":" +(System.currentTimeMillis()/1000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
相关文章推荐
- Java数据库编程中查询结果的表格式输出
- Java数据库编程中查询结果的表格式输出
- java编写程序输出下列结果
- ZOJ 1205题解本来是一道大数运算水题,可是却纠结了很久,原因是没能真正读懂题意,要求的计算必须是一一对应输出即使前面出现几个0最后也要把前面的0输出,看别人用C++自己还是两个都提交了结果还是C占的内存少。
- java基础问题---------下面的程序代码输出的结果是多少
- Java数据库查询结果的输出
- java调用C的exe文件并传入参数,读出exe输出结果
- java三目运算符输出结果
- 用java把从数据库中查询出的结果集重新按照结果中的几个字段重新排序
- 汇编 输入几个数子进行比较 不同条输出不同的结果 三个相同输出2 两个同输出1 不同输出0
- Java程序运行结果输出到一个文件中去,结果显示乱码
- Java数据库编程中查询结果的表格式输出
- Java数据库编程中查询结果的输出
- 用java编写程序输出下列结果
- java调用.bat,.cmd或执行cmd命令并将输出结果显示的代码
- Java数据库编程中查询结果的表格式输出
- java将几个数组添加到LinkedList中后再遍历输出
- Java数据库编程中查询结果的表格式输出
- Java字符串空格处理(无论有几个空格,都输出为1个空格,去除字符串前后的全角空格)
- java结果输出,知其所以然