62,612
社区成员
发帖
与我相关
我的任务
分享
package com.qf.test01;
import java.util.ArrayList;
import java.util.List;
/**
* @author qf
* @create 2018-09-13 17:47
*/
public class MyList {
private List list = new ArrayList();
public void add(){
list.add("qf");
}
public int size(){
//System.out.println("MyList.size:"+list.size());
return list.size();
}
}
}
package com.qf.test01;
/**
* @author qf
* @create 2018-09-13 17:45
*/
public class ThreadA extends Thread {
private MyList myList;
public ThreadA(MyList myList) {
this.myList = myList;
}
@Override
public void run() {
try {
System.out.println("a run");
for (int i = 0; i < 10; i++) {
myList.add();
System.out.println("添加了"+(i+1)+"个元素");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.qf.test01;
/**
* @author qf
* @create 2018-09-13 17:45
*/
public class ThreadB extends Thread {
private MyList myList;
public ThreadB(MyList myList) {
this.myList = myList;
}
@Override
public void run() {
try {
System.out.println("b run");
while (true){
if(myList.size() == 5){
System.out.println("线程b要退出了");
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.qf.test01;
/**
* @author qf
* @create 2018-09-14 9:23
*/
public class Test {
public static void main(String[] args) {
MyList list = new MyList();
ThreadA a = new ThreadA(list);
a.setName("a");
a.start();
ThreadB b = new ThreadB(list);
b.setName("b");
b.start();
}
}
if(myList.size() == 5)
{
System.out.println("线程b要退出了");
throw new InterruptedException();
}
是一个状态发现的过程,这个语句的执行线程必须有机会执行判断,而这个判断取决于CPU的调度,很不可靠,
(其实Java.util.ConcurentHashMap的算法就有这个问题,文档中明确进行了说明,这个场景可用于弱一致的判断)。
要正确实现if(myList.size()==5),这个需要保证在执行语句线程调用的时候,其他共享数据线程不会write数据,否则结果不可预知。
如果只有两个线程,即读写线程,那么可以使用wait/notify(All),或者一些高级锁实现。
要解决这样的问题,就要引入支持并发的队列做缓冲区或者使用SynchronsQueue实现。