我来到这里是为了让我忙碌更长时间的问题。
为清楚起见,这就是我在做的事情:
我正在创建一个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方法。
我将不胜感激。
谢谢,迈克尔
答案 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;
}
}