Java线程在独立对象之间处理

Java线程在独立对象之间处理,java,multithreading,Java,Multithreading,当我试图学习Java线程时,通常会遇到在同一个类中包含wait()和notify()的代码示例(实际上几乎所有这些示例都是生产者-消费者示例)。在谷歌搜索各种示例后,不幸的是,我无法找到我需要的案例,即: 管理器线程最初创建n个线程(并启动它们),其中http get请求在单个线程中完成 对于单个辅助线程,完成其生命周期大约需要20-30秒 在这里,我的线程经理必须知道哪些工人已经完成,并用一个新线程替换完成线程 我考虑过这样一种方法(设n为5): List runnables=new Ar

当我试图学习Java线程时,通常会遇到在同一个类中包含
wait()
notify()
的代码示例(实际上几乎所有这些示例都是生产者-消费者示例)。在谷歌搜索各种示例后,不幸的是,我无法找到我需要的案例,即:

  • 管理器线程最初创建n个线程(并启动它们),其中http get请求在单个线程中完成
  • 对于单个辅助线程,完成其生命周期大约需要20-30秒
  • 在这里,我的线程经理必须知道哪些工人已经完成,并用一个新线程替换完成线程
我考虑过这样一种方法(设n为5):

List runnables=new ArrayList();
对于(int i=0;i<5;i++){
添加(新的MyWorker(参数));
}
for(可运行myWorker:runnables){
myWorker.run();
}

由于
wait()
不支持多个对象,因此我无法从这里继续下去。另一个解决方案是在管理器线程上实现繁忙等待,为每个工作线程调用一些isFinished标志。但我不确定这是否是一种好的方法(据我所知,这是一种资源浪费)

在Java 6及更高版本中,有一个现成的工具,以executor框架的形式出现

由于您希望有一个固定的线程池,因此最好使用:

ExecutorService service = Executors.newFixedThreadPool(5);
然后,您可以使用
.execute()
方法(由
executer
接口定义)提交
Runnable
实例。一旦池中的线程可用,它们将被提交到工作队列并退出队列

如果您的单个线程工作方法返回一个值(即,它们实现了
可调用的
),那么您可以使用
.submit()
方法(由
ExecutorService
定义,也是一个扩展
Executor
的接口),它将返回一个
将来的
,您将从中
获取()
计算值

终止线程池有多种方式:
.shutdown()
是最基本的方法,它将同步等待仍处于活动状态的线程终止(并防止提交新作业)

Javadocs:

其他链接:(但不包括Java7的
ForkJoinPool


PS:多幸运啊,任务执行的范围;)

在Java 6及更高版本中,有一个随时可用的工具,其形式是executor框架

由于您希望有一个固定的线程池,因此最好使用:

ExecutorService service = Executors.newFixedThreadPool(5);
然后,您可以使用
.execute()
方法(由
executer
接口定义)提交
Runnable
实例。一旦池中的线程可用,它们将被提交到工作队列并退出队列

如果您的单个线程工作方法返回一个值(即,它们实现了
可调用的
),那么您可以使用
.submit()
方法(由
ExecutorService
定义,也是一个扩展
Executor
的接口),它将返回一个
将来的
,您将从中
获取()
计算值

终止线程池有多种方式:
.shutdown()
是最基本的方法,它将同步等待仍处于活动状态的线程终止(并防止提交新作业)

Javadocs:

其他链接:(但不包括Java7的
ForkJoinPool


PS:多幸运啊,任务执行的范围;)

您可以使用
信号量
等待/通知
方法来完成您要做的事情。方法是:

  • 使用一次允许的最大线程数初始化信号量
  • 等待任务在
    队列中可用
  • 获取一个
    信号灯
  • 运行任务并在完成时释放
    信号灯
  • 将所有这四个步骤都放在while循环中,您就可以使用任务执行器了。这只是为了学习,正如@fge所说,已经存在
    ThreadPoolExecuter
    ,它可以为您做同样的事情,并且更优化

    import java.util.LinkedList;
    import java.util.Queue;
    import java.util.concurrent.Semaphore;
    
    public class ThreadExecuter extends Thread {
    
        Queue<Runnable> tasks = new LinkedList<Runnable>();
        Semaphore s;
        Object bin = new Object();
    
        public ThreadExecuter(int n) {
            s = new Semaphore(n);
        }
    
        public void addTask(Runnable r) {
            synchronized (bin) {
                tasks.add(r);
                bin.notifyAll();
            }
        }
    
        public void run() {
            while (true) {
                try {
                    final Runnable r;
                    synchronized (bin) {
                        while (tasks.isEmpty())
                            bin.wait();
                        r = tasks.poll();
                    }
    
                    s.acquire();
                    new Thread() {
                        public void run() {
                            r.run();
                            s.release();
                        }
                    }.start();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
        }
    }
    
    import java.util.LinkedList;
    导入java.util.Queue;
    导入java.util.concurrent.Semaphore;
    公共类ThreadExecuter扩展线程{
    队列任务=新建LinkedList();
    信号量s;
    Object bin=新对象();
    公共线程执行器(int n){
    s=新信号量(n);
    }
    公共void addTask(可运行的r){
    已同步(bin){
    任务。添加(r);
    bin.notifyAll();
    }
    }
    公开募捐{
    while(true){
    试一试{
    最终可运行r;
    已同步(bin){
    while(tasks.isEmpty())
    bin.wait();
    r=tasks.poll();
    }
    s、 获得();
    新线程(){
    公开募捐{
    r、 run();
    s、 释放();
    }
    }.start();
    }捕捉(中断异常e){
    //TODO自动生成的捕捉块
    e、 printStackTrace();
    }
    }
    }
    }
    
    主要方法如下所示:

    import java.util.Random;
    
    public class ThreadTest {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
                /* to make maximum 10 threads each running 1 runnable */
            ThreadExecuter executer = new ThreadExecuter(10);
            executer.start();
    
            for(int i = 0; i < 5000; i++) {
                        /* add task in executer, this is non blocking */
                executer.addTask(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Task Executed in " 
                                            + Thread.currentThread().getId());
                        try {
                            Thread.sleep(new Random().nextInt(8000));
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    
    }
    
    import java.util.Random;
    公共类线程测试{
    /**
    *@param args
    */
    公共静态void main(字符串[]args){
    /*使每个运行1个线程的线程最多10个可运行*/
    ThreadExecuter executer=新的ThreadExecuter(10);
    executer.start();
    对于(int i=0;i<5000;i++){
    /*在executer中添加任务,这是非阻塞的*/
    addTask(新的Runnable()){
    @凌驾
    公开募捐{
    System.out.println(“在中执行的任务”
    +太尔