在计时器中启动多个线程

时间:2014-02-19 13:42:41

标签: java multithreading timer

我来到这里是为了让我忙碌更长时间的问题。

为清楚起见,这就是我在做的事情:

我正在创建一个java程序,它以Graph的形式关注PLC中的数据。更具体一点,我正在运行一个带TimerTask的Timer,它可以在每个周期内保持从PLC加载数据。但是这里出现了主要问题 - 从数据块中获取的单个变量大约需要250ms。我想同时阅读更多变量。所以基本上,它需要250毫秒的变量。 我认为这里的线程对于实现梦想目标是绝对必要的。

更深入地了解代码:

从一开始。我正在启动一个Timer:

Timer timer = new Timer();
timer.schedule(dc, 0, period);

dc是DataCollector类的实例,它从PLC获取数据。 DataCollector中方法run()的重要片段是这样的:

@Override
public void run() {
    variables = readFromPlc();

这就是我所面临的问题。 readFromPlc从另一个名为TCP的类调用read()。在那个类中,我创建了与变量一样多的线程。但问题是如何在一段时间内保持这些线程的运行!我在构造函数中创建了这些线程,并且第一次,它们当然调用run()并从plc正确读取数据并将它们显示为图形。但是那些线程的结束 - 不会再次调用run()。

如果我可以反复停止并继续线程,那就太好了。但是我被安排在这里。 PS:我不能简单地创建一个新的TCP实例,因为我有一些其他方法和功能代码,我不想再运行。

或者非常简单: 我想在每个时间段(每秒一次)运行线程的run方法。

我将不胜感激。

谢谢,迈克尔

1 个答案:

答案 0 :(得分:1)

正如评论中所述,有关如何使用ExecutorService

来完成此 的建议

编辑/注意:此示例仅显示基本方法。在实际应用程序中,一旦不再需要shutdown(),您必须确保ExecutorService被调用(或者允许核心线程超时)。

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ScheduledMultiThread
{
    public static void main(String[] args)
    {
        Timer timer = new Timer();
        long period = 1000;

        DataCollector dc = new DataCollector();
        timer.schedule(dc, 0, period);


    }
}

class DataCollector extends TimerTask
{
    private ExecutorService executorService;

    @Override
    public void run()
    {
        int variables = readFromPlc();
        if (executorService == null)
        {
            executorService = Executors.newFixedThreadPool(variables);
        }

        List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
        for (int i=0; i<variables; i++)
        {
            Runnable task = createTaskForVariable(i);
            tasks.add(Executors.callable(task));
        }
        try
        {
            executorService.invokeAll(tasks);
        }
        catch (InterruptedException e)
        {
            Thread.currentThread().interrupt();
        }
    }

    private Runnable createTaskForVariable(final int variable)
    {
        Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                executeTaskFor(variable);
            }
        };
        return runnable;
    }


    // Dummy implementations
    private void executeTaskFor(int variable)
    {
        System.out.println("Working for variable "+variable);
        try
        {
            Thread.sleep((long)(200+Math.random()*200));
        }
        catch (InterruptedException e)
        {
            Thread.currentThread().interrupt();
        }
        System.out.println("Working for variable "+variable+" DONE");
    }

    private int readFromPlc()
    {
        return 8;
    }


}