首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用locks.ReentrantLock实现Java线程池

用locks.ReentrantLock实现Java线程池
EN

Stack Overflow用户
提问于 2014-04-25 12:12:57
回答 1查看 1.5K关注 0票数 0

我是爪哇大学的新人。我只是在尝试线程,我想要创建类似线程池的东西(如果这就是我正在做的事情的话)。

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

代码语言:javascript
复制
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();
      }
   }
}

当我运行代码时,新线程将永远被触发,任务计数只会减少两三次.

输出的最后一行(读取时间作为要执行的任务):

代码语言:javascript
复制
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

然后给出堆栈溢出的答案,看看如何使用ReentrantLock:https://stackoverflow.com/a/12510490/988591

这是因为闭包不能修改外部变量(使用数组值):http://c2.com/cgi/wiki?ClosuresThatWorkAroundFinalLimitation

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-25 12:25:51

你不能使用内置线程池功能吗?

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

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

我不想建议您的代码的其他一切都是“好的”(创建一个健壮的线程池实现可能是一个相当困难和复杂的任务),但是一个可能避免问题的最小的更改可能是。

代码语言:javascript
复制
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();
      }
   }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23292819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档