0

我只是在学习一些关于 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();
}

}

有人可以帮助指出我做错的一切,可能很多。

4

3 回答 3

0

的测试listSize > 0没有正确同步。执行检查时列表可能是非空的,但在线程调用时实际上是空的getLink()getLink()使用returnboolean而不是 void可能会更容易,哪里true会指示列表为空,并false指示它不是,然后每个线程可以继续调用该方法,直到它返回falsegetLink()在尝试删除项目之前,您还必须检查列表顶部是否为空。

@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()
}
于 2012-09-07T13:52:42.067 回答
0

使用多线程方法去抓取索引 0 处的元素是没有意义的,因为同步自旋锁的执行(几乎)与单线程应用程序相同。多个线程可以读取,但只有一个线程可以写入。

于 2012-09-07T13:53:41.730 回答
0

基本问题是您正在做的事情最好由一个线程完成。JVM 会处理此问题,但允许一个线程锁定锁并在其他线程甚至有机会之前消耗所有元素。

于 2012-09-07T13:53:43.320 回答