【发布时间】:2015-08-04 17:03:32
【问题描述】:
我试图通过在 java 中使用 Thread 来解决有关 list.add 和 list.remove 的问题。
假设我们在玩 Stack
这是我的堆栈定义类..
import java.util.ArrayList;
public class Stack {
private int size;
private int maxSize;
private final ArrayList<Object> list;
public Stack(int size) {
this.size = 0;
this.maxSize = size;
this.list = new ArrayList<Object>(size);
}
public boolean push(Object o) {
if (size >= maxSize) {
return false;
}
this.list.add(0, o);
this.size++;
return true;
}
public Object pop() {
Object o;
if (this.size == 0) {
return null;
}
o = this.list.remove(0);
this.size--;
return o;
}
public int size() {
return this.size;
}
}
这是我们如何在 Java 中使用线程中的堆栈
final Stack stack = new Stack(4);
for(int i = 0; i < 10000; i++) {
final String data = "hello " + i;
final int x = i;
new Thread(new Runnable() {
public void run() {
if(x % 2 == 0) {
System.out.println(stack.push(data));
} else {
System.out.println(stack.pop());
}
}
}).start();
}
所以基本上我们只需要创建 10000 个线程来操作 Stack 对象。
stack.push 结果为真(如果堆栈尚未满)或假(如果堆栈已满)
stack.pop 如果堆栈为空,则返回 null
问题是:上面的 Stack 实现有什么问题以及如何解决?
到目前为止,我的分析是线程如何在 java 中运行。线程并行运行而不是顺序运行。我试图执行程序,有时会弹出异常IndexOutOfBounds。如果我的分析是真的(或接近),有没有办法避免异常?也许在 Stack 类中包含一些检查方法?
如果我的分析是错误的,那么上面的实现有什么问题?以及如何解决?
【问题讨论】:
-
您的堆栈实现不是线程安全的。线程安全就是保护可变状态,以便对象在并发访问时经历一致、可靠的状态转换。不幸的是,您的课程会受到竞争条件的影响,这将使您的对象处于未定义或不一致的状态。使用锁定来强制线程互斥是一种确保原子状态转换的简单(如果不是高性能)方法。
标签: java multithreading object arraylist