有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程试图找出线程和Java

我正在学习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();
}

}

有人能帮我指出我做错了什么吗?可能很多


共 (3) 个答案

  1. # 1 楼答案

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

  2. # 2 楼答案

    最基本的问题是,你正在做的事情最好由一个线程来完成。JVM可以处理这个问题,但允许一个线程锁定锁并在其他线程有机会之前使用所有元素

  3. # 3 楼答案

    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()
    }