使用locks.ReentrantLock实现Java基本线程池

时间:2014-04-25 12:12:58

标签: java multithreading concurrency locking reentrantlock

我是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

我确信我使用Threads或lock的方式肯定存在完全错误..但作为一个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

1 个答案:

答案 0 :(得分:1)

你能否使用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();
      }
   }
}
相关问题