gpt4 book ai didi

java - 为什么我的多线程代码会导致挂起?

转载 作者:行者123 更新时间:2023-11-30 08:01:07 24 4
gpt4 key购买 nike

我研究java并发。

我试图估计执行时间取决于线程数(读和写)

我的代码:

public class Task5 {
public static int [] readerThreadCount = {1,10,100,1000};
public static int [] writerThreadCount = {10, 1000, 1000000};


public static void main(String[] args) throws InterruptedException {
for (int readCount : readerThreadCount) {
for (int writeCount : writerThreadCount) {
System.out.println(readCount + "/" + writeCount + " = " + test(readCount, writeCount, new ArrayHolderBySynchronized()));
}
}

}

private static long test(int readCount, int writeCount, ArrayHolder arrayHolder) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(readCount + writeCount);
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < readCount; i++) {
threads.add(new Thread(new ArrayReader(arrayHolder, countDownLatch)));
}
for (int i = 0; i < writeCount; i++) {
threads.add(new Thread(new ArrayWriter(arrayHolder, countDownLatch)));

}
for(Thread thread:threads){
thread.start();
}
countDownLatch.await();//all threads started
long start = System.currentTimeMillis();
for (Thread thread : threads) {
thread.join();
}
return System.currentTimeMillis() - start;

}
}

class ArrayHolderBySynchronized extends ArrayHolder {

@Override
public synchronized int get(int index) {
return arr[index];
}

@Override
public synchronized void write(int index, int value) {
arr[index] = value;
}
}

class ArrayReader implements Runnable {
ArrayHolder arrayHolder;
CountDownLatch countDownLatch;

ArrayReader(ArrayHolder arrayHolder, CountDownLatch countDownLatch) {
this.arrayHolder = arrayHolder;
this.countDownLatch = countDownLatch;
}

@Override
public void run() {
countDownLatch.countDown();
arrayHolder.get(new Random().nextInt(ArrayHolder.ARRAY_SIZE));
}
}

class ArrayWriter implements Runnable {
ArrayHolder arrayHolder;
CountDownLatch countDownLatch;

ArrayWriter(ArrayHolder arrayHolder, CountDownLatch countDownLatch) {
this.arrayHolder = arrayHolder;
this.countDownLatch = countDownLatch;
}

@Override
public void run() {
countDownLatch.countDown();
arrayHolder.write(new Random().nextInt(ArrayHolder.ARRAY_SIZE), -1);
}
}

abstract class ArrayHolder {
public static int ARRAY_SIZE = 1_000_000;
protected int[] arr = generateArray();

private int[] generateArray() {
int[] arr = new int[ARRAY_SIZE];
for (int i = 0; i < ARRAY_SIZE; i++) {
arr[i] = i + 1;
}
return arr;
}

public abstract int get(int index);

public abstract void write(int index, int value);
}

它输出

1/10 = 0
1/1000 = 1

然后挂起。

我不知道为什么。

请帮忙。

最佳答案

它不会挂起,启动 1000000 个线程只需要比启动 1000 个线程长 1000 倍的时间(在我的机器上需要几分钟):

> java Task5

1/10 = 0
1/1000 = 1
1/1000000 = 63
10/10 = 0
10/1000 = 0
10/1000000 = 60
100/10 = 0
100/1000 = 0
100/1000000 = 63
1000/10 = 0
1000/1000 = 0
1000/1000000 = 60

您的下一个问题可能是为什么您的测试报告的持续时间为 60 毫秒,而执行时间只有几分钟。这是因为启动线程比对锁存器进行倒计时或读取或写入单个数组元素要昂贵得多,而且您只能测量后者。

关于java - 为什么我的多线程代码会导致挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31905083/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com