如何为用户指定的时间运行一个线程?

时间:2013-09-15 23:23:21

标签: java multithreading concurrency executorservice

创建一个基于混合并在包含解Vector的群体中进行扰动的程序。

所以我创建的for loop会在用户指定的时间后停止。 在循环内部,我将调用5个程序,我认为如果我将每个程序放在一个线程中将使程序在同一时间内制作更多的解决方案而不是调用普通方法。

这里5创建了5个线程,但是当我启动它们时,即使我使用Thread.stopThread.suspendThread.interruptThread.destroy,也不想停止

这是我的代码,你可以帮我解决一下你的想法吗?

我插入了一个新变量:

public volatile boolean CrossOpb = true;`

这是我的代码:

Thread CrossOp = new Thread(new Runnable() {
public void run() {
   while(CrossOpb == true){
    int rdmCross2=(int) (Math.random() * allPopulation.size())  ; // Crossover 1st vector
    int rdmCross1=(int) (Math.random() * allPopulation.size())  ;
    Vector muted = new Vector();
    Vector copy = copi((Vector) allPopulation.get(rdmCross2));
    Vector callp = copi((Vector) allPopulation.get(rdmCross1));
    muted = crossover(callp, copy);
    System.out.println("cross over Between two Randoms ----------->");
    affiche_resultat(muted);
    allPopulation.add(muted);
   }
}

});

循环:

CrossOp.setDaemon(true);

int loop = 1;
long StartTime = System.currentTimeMillis() / 1000;
for (int i = 0; i < loop; ++i) { 
    loop++;
    if (timevalue < ((System.currentTimeMillis() / 1000) - StartTime)) {
        loop = 0;
     CrossOpb = false;   
    }
CrossOp.start();
}

3 个答案:

答案 0 :(得分:2)

我已经回答了similar question。在那种情况下,它是C#,但概念是相同的。

必须杀死线程。线程必须按自己的意愿退出。 只需将volatile boolean变量置于某处,并将其设置为true / false,当您希望线程终止时,然后在线程中将while (true)替换为while (myVariable == true/false)

无论如何,你说:

  

在循环内部,我将调用5个程序ant我认为如果我将每个程序放在一个线程中将使程序在同一时间内制作更多的解决方案而不是调用普通方法。

嗯,这通常都是假的。如果这些过程是依赖于数据的(每个过程都取决于前一个过程的结果),那么将它们放在线程上将不会改变任何内容。将迭代放在管道中可能更聪明,因此您有5个线程执行连续迭代的步骤。我不确定这是否可能用于遗传算法,无论如何你必须处理一些特殊情况(例如,一个突变,它会改变部分计算迭代的数量)。

答案 1 :(得分:1)

如何在特定时间内运行Thread

这里的基本方法是继续计算Thread已运行多长时间并退出并返回结果,在这种情况下,这里是Thread执行多长时间的详细信息。

注意:您必须使用System.nanoTime(),因为System.currentTimeMillis()每次在方法中调用它时都会返回相同的内容。

我使用Random数字计算每个Callables的不同生命周期,以便您可以看到他们在指定的时间内没有执行完全但是他们非常接近,三角洲的差异非常一致,至少在我的机器上是这样。

以下是Gist以下代码,以便于访问。

package com.stackoverflow.Q18818482;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;

public class Question18818482
{
    public static Random RND;

    static
    {
        RND = new Random();
    }

    public static void main(final String[] args)
    {
        try
        {
            final ExecutorService es = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
            final List<Future<String>> results = new ArrayList<>(10);
            for (int i = 0; i < 10; i++)
            {
                results.add(es.submit(new TimeSliceTask(RND.nextInt(10), TimeUnit.SECONDS)));
            }
            es.shutdown();
            while(!results.isEmpty())
            {
                final Iterator<Future<String>> i = results.iterator();
                while (i.hasNext())
                {
                    final Future<String> f = i.next();
                    if (f.isDone())
                    {
                        System.out.println(f.get());
                        i.remove();
                    }
                }
            }
        }
        catch (InterruptedException e)
        {
            throw new RuntimeException(e);
        }
        catch (ExecutionException e)
        {
            throw new RuntimeException(e);
        }
    }

    public static class TimeSliceTask implements Callable<String>
    {
    private final long timeToLive;
    private final long duration;


    public TimeSliceTask(final long timeToLive, final TimeUnit timeUnit)
    {
        this.timeToLive = System.nanoTime() + timeUnit.toNanos(timeToLive);
        this.duration = timeUnit.toMillis(timeToLive);
    }

    @Override
    public String call() throws Exception
    {
        while( timeToLive <= System.nanoTime() )
        {
            // simulate work here
            Thread.sleep(500);
        }
        final long end = System.nanoTime();
        return String.format("Finished Elapsed Time = %d, scheduled for %d", TimeUnit.NANOSECONDS.toMillis(timeToLive - end), this.duration );
    }
    }
}

以下是运行输出的内容

注意:所有时间都以毫秒为单位

Finished Elapsed Time = 999, scheduled for 1000
Finished Elapsed Time = 2998, scheduled for 3000
Finished Elapsed Time = 5999, scheduled for 6000
Finished Elapsed Time = 1994, scheduled for 2000
Finished Elapsed Time = 8994, scheduled for 9000
Finished Elapsed Time = 6993, scheduled for 7000
Finished Elapsed Time = 6993, scheduled for 7000
Finished Elapsed Time = 5993, scheduled for 6000
Finished Elapsed Time = 5998, scheduled for 6000

答案 2 :(得分:-1)

在读完关于线程的整个昨晚之后,我发现解决问题的方法并不那么难 我的想法是编辑线程内停止循环的条件,所以我们通过给它一个特定的时间来控制它,这是我的例子:

class ProcessorCordm extends Thread {
    int runningtime;
    public ProcessorCordm(int runningtime) {
        this.runningtime = runningtime;
    }
    public void run() {
        int loop = 1;
        long StartTime = System.currentTimeMillis() / 1000;
        for (int i = 0; i < loop; ++i) {
            int rdmCross2 = (int) (Math.random() * allPopulation.size()); // Crossover 1st vector
            int rdmCross1 = (int) (Math.random() * allPopulation.size());
            Vector muted = new Vector();
            Vector copy = copi((Vector) allPopulation.get(rdmCross2));
            Vector callp = copi((Vector) allPopulation.get(rdmCross1));
            muted = crossover(callp, copy);
            System.out.println("cross over Between two Randoms ----------->");
            affiche_resultat(muted);
            addsolution(muted);
            loop++;
            if (timevalue < ((System.currentTimeMillis() / 1000) - StartTime)) {
                loop = 0;
            }
        }
    }
}

因此,如果我想线程 10秒,我只需要:

 ProcessorCoG CrossOpg = new ProcessorCoG(10);

对于我的情况,我必须同时为特定的 TimeValue 调用许多线程,所以我使用了ExecutorService类:

            ProcessorCoG CrossOpg = new ProcessorCoG(timevalue);//extends Thread class
            ProcessorCordm CrossOp = new ProcessorCordm(timevalue);//extends Thread class
            ProcessorCordm CrossOp2 = new ProcessorCordm(timevalue);//extends Thread class
            MutateGb MutGb = new MutateGb(timevalue);//extends Thread class
            MutateRdm MutRdm = new MutateRdm(timevalue);//extends Thread class
            MbsRdm MbsR = new MbsRdm(timevalue);//extends Thread class
            ExecutorService executor = Executors.newFixedThreadPool(6);
            executor.submit(MutGb);
            executor.submit(MutRdm);
            executor.submit(CrossOp);
            executor.submit(CrossOp2);
            executor.submit(CrossOpg);
            executor.submit(MbsR);