我来这里是为了回答问题,这让我忙了很长时间。
为了清楚起见,这就是我正在做的事情:
我正在创建一个java程序,它以图形的形式关注PLC中的数据。更具体地说,我正在使用 TimerTask 运行一个计时器,它会在每个周期从该 PLC 加载数据。但主要问题来了——从数据 block 读取单个变量大约需要 250ms。我想同时读取更多变量。所以基本上,它需要变量*250ms 的时间。 我认为这里的线程对于实现梦想的目标是绝对必要的。
更深入地了解代码:
从一开始。我正在启动一个计时器,如下所示:
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 方法。
如果有任何帮助,我将不胜感激。
谢谢,迈克尔
最佳答案
正如评论中提到的,关于如何使用 ExecutorService
来完成此操作的建议
编辑/注意:此示例仅显示基本方法。在实际应用程序中,您必须确保在不再需要 ExecutorService
时调用 shutdown()
(或者允许核心线程超时)。
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;
}
}
关于java - 在计时器中启动多个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21882285/