我只是在学习Java中的线程,我想知道是否有人可以帮助我。
我创建了一个包含10个整数的列表。我想要做的是让多个线程进入,在索引0处获取整数,打印并删除它。我希望这种情况发生在列表中没有更多数字之前。到目前为止,这是我的代码。
public class SlothTest implements Runnable{
static ArrayList<Object> test = new ArrayList<>();
static int listSize;
public static void main(String[] args) {
for (int i = 0; i < 10; i++){
test.add(i);
}
SlothTest runner = new SlothTest();
Thread alpha = new Thread(runner);
Thread beta = new Thread(runner);
alpha.setName("Alpha thread");
beta.setName("Beta thread");
alpha.start();
beta.start();
}
@Override
public void run() {
listSize = test.size();
while (listSize > 0){
getLink();
}
}
private synchronized void getLink(){
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " printed " + test.indexOf(listSize - 1));
test.remove(0);
listSize = test.size();
}
}
有人可以帮助指出我做错的一切,可能很多。
答案 0 :(得分:0)
listSize > 0
的测试未正确同步。执行检查时列表可能是非空的,但在线程调用getLink()
时实际上是空的。让getLink()
返回boolean
而不是void可能会更容易,true
表示列表为空,false
表示不是false
表示每个帖子都可以继续调用方法,直到它返回getLink()
。在尝试删除项目之前,您还必须检查@Override
public void run() {
while (getLink());
}
private synchronized boolean getLink(){
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " printed " + test.indexOf(test.size() - 1));
if(!test.isEmpty()){
test.remove(0);
}
return !test.isEmpty()
}
顶部的列表是否为空。
{{1}}
答案 1 :(得分:0)
使用多线程方法去索引0处的元素是没有意义的,因为同步的自旋锁将执行(几乎)与单线程应用程序相同。多个线程可以读取,但只有一个可以写入。
答案 2 :(得分:0)
基本问题是你正在做一些最好由一个线程完成的事情。 JVM处理这个问题,但允许一个线程锁定锁并在其他线程获得机会之前使用所有元素。