gpt4 book ai didi

java - 信号量 - 为什么我的线程一个接一个地运行而不是并发运行?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:24:24 25 4
gpt4 key购买 nike

我正在尝试编写一个程序,在 Main 类中可以启动未知数量的新线程。每个线程依次调用 Singleton Copier 类,该类应调用文件传输操作。

我的目标是,无论线程请求的数量如何,都是将并发传输的数量限制为 2 个传输,所以我想用 Semaphore 来解决它。我的问题是,线程似乎一个接一个地运行,而不是并发运行。

这是我尝试做的:

public class Copier {

private static final int POOL_SIZE = 2;
private static volatile Copier instance = null;
private static Semaphore semaphore;

private Copier() {

}

public static Copier getInstance() {
if (instance == null) {
synchronized (Copier.class) {
if (instance == null) {
instance = new Copier();
semaphore = new Semaphore(POOL_SIZE);
}
}
}
return instance;
}

public void fileTransfer(CopyThread copyThread) {
try {
semaphore.acquire();
System.out.println("Running thread...");
copyThread.run();

} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
semaphore.release();
System.out.println("Thread released..");
}
}
}

这是我的 Main 类:

public class Driver {
public static void main(String[] args) {
Copier copier = Copier.getInstance();
CopyThread copyThread1 = new CopyThread();
CopyThread copyThread2 = new CopyThread();

copier.fileTransfer(copyThread1);
copier.fileTransfer(copyThread2);
}
}

运行它时 - 您可以通过输出看到线程一个接一个地运行,而我的目的是最多有 2 个并发线程。我做错了什么?

Running thread...
3.998784MB were transferred in 5.902514932 seconds
Thread released..
Running thread...
4.062673MB were transferred in 7.199550077 seconds
Thread released..

最佳答案

你应该调用 start() 而不是 run() 否则它不会启动你的线程,这样传输将按顺序完成,这实际上是当前问题的根本原因。

无论如何,对我来说,您的代码应该被重写为 Copier 类甚至不应该 start() 线程,因为这不是它的职责。

1。重写方法 fileTransfer()

public void fileTransfer() {
try {
semaphore.acquire();
System.out.println("Running transfer...");
// Code that performs the transfer
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
System.out.println("Thread released..");
}
}

2。正确实现CopyThreadrun()方法

@Override
public void run() {
// Here I call fileTransfer() on Copier instead of the other way around
Copier.getInstance().fileTransfer();
}

3。使信号量非静态和最终

private final Semaphore semaphore;

private Copier() {
this.semaphore = new Semaphore(POOL_SIZE);
}

4。使用内部类来延迟创建您的实例

public class Copier {
...
public static Copier getInstance() {
return Holder.instance;
}
...
private static class Holder {
private static final Copier instance = new Copier();
}
}

5。重写你的 main 方法

public static void main(String[] args) throws Exception {
CopyThread copyThread1 = new CopyThread();
CopyThread copyThread2 = new CopyThread();

copyThread1.start();
copyThread2.start();
}

输出:

Running transfer...
Running transfer...
Thread released..
Thread released..

关于java - 信号量 - 为什么我的线程一个接一个地运行而不是并发运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39609913/

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