gpt4 book ai didi

Java基本线程池带锁的实现.ReentrantLock

转载 作者:行者123 更新时间:2023-12-01 13:05:37 25 4
gpt4 key购买 nike

我是 Java 新手。我只是在尝试线程,我想创建类似线程池的东西(如果这实际上是我正在做的事情......)。

基本上,我有一个 while 循环,它会触发线程,直到仍然有任务要执行&&,同时最大并发线程不大于 n。每个线程使用 java.util.concurrent.locks.ReentrantLock 围绕任务计数变量提供锁,该变量在每个线程中减少,并且线程计数变量在线程启动时增加,并在线程结束前减少(代码闻起来?):

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test {
public static void main(String[] args) {

//overcome limitation of closure not being able to modify outer variable with arr.
final int[] runningThreads = {0};
final int[] taskcount = {10};

final Lock _mutex = new ReentrantLock(true);

int maxThreadQty = 3;


while ((taskcount[0] > 0) && (runningThreads[0] < maxThreadQty)) {

new Thread("T") {
public void run() {
System.out.println("New Thread Started");
_mutex.lock();
runningThreads[0]++;
System.out.println("Running Threads: " + runningThreads[0]);
System.out.println("Times to go: " + taskcount[0]);
_mutex.unlock();
// actually do something;
_mutex.lock();
taskcount[0]--;
runningThreads[0]--;
_mutex.unlock();
}

}.start();
}
}
}

当我运行代码时,新线程不断被激发,任务数量只减少了两到三倍……

输出的最后几行(读取时间作为待完成的任务):

Running Threads: 565
Times to go: 8
Running Threads: 566
Times to go: 8
Running Threads: 567
Times to go: 8
Running Threads: 568
Times to go: 8
Running Threads: 569
Times to go: 8
Running Threads: 570
Times to go: 8
Running Threads: 571
Times to go: 8
Running Threads: 572
Times to go: 8
Running Threads: 573
Times to go: 8
Running Threads: 574
Times to go: 8
Running Threads: 575
Times to go: 8

CTRL-C

我确信我使用线程或锁的方式一定有问题。但是作为一个java新手,我可能会错过很多东西(甚至可能是最基本的),需要一些帮助和一些让我回到正确的道路上将非常感激......!谢谢。

我用它作为线程的引用:http://tutorials.jenkov.com/java-concurrency/creating-and-starting-threads.html

然后通过这个 stackoverflow 答案来了解如何使用 ReentrantLock:https://stackoverflow.com/a/12510490/988591

这对于闭包无法修改外部变量的解决方法(使用数组值): http://c2.com/cgi/wiki?ClosuresThatWorkAroundFinalLimitation

最佳答案

你不能使用 built in thread pool功能?

如果不是,问题是 runningThreads 在每个线程启动并获取锁之前不会增加。实际上,主线程可能会运行相当长的时间,同时无限制地旋转新线程。

一种解决方案可能是在启动新线程之前增加主线程上的 runningThreads 变量,但在每个工作线程内减少该变量。

我不想暗示您的代码的其他所有内容都是“好的”(创建强大的线程池实现可能是一项相当困难且复杂的任务),但可以避免该问题的最小更改可能是

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test {
public static void main(String[] args) {

//overcome limitation of closure not being able to modify outer variable with arr.
final int[] runningThreads = {0};
final int[] taskcount = {10};

final Lock _mutex = new ReentrantLock(true);

int maxThreadQty = 3;


while ((taskcount[0] > 0) && (runningThreads[0] < maxThreadQty)) {
System.out.println("New Thread Started");
_mutex.lock();
runningThreads[0]++;
System.out.println("Running Threads: " + runningThreads[0]);
System.out.println("Times to go: " + taskcount[0]);
_mutex.unlock();
new Thread("T") {
public void run() {
// actually do something;
_mutex.lock();
taskcount[0]--;
runningThreads[0]--;
_mutex.unlock();
}

}.start();
}
}
}

关于Java基本线程池带锁的实现.ReentrantLock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23292819/

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