我正在用Java预测一个监控客户端,它将从/proc
读取信息。我有一个主要课程MonitoringClient
和ProcParser
课程。我的ProcParser
扩展了Thread
。
我认为实例化很多(四个:cpu,内存,磁盘和网络)ProcParser
对象,传递我想在构造函数中测量的组件之一是一个很好的方法。然后,在run方法中,我在之间切换 - 每个对象将解析其中一个。代码类似于:
ProcParser pp_Cpu = new ProcParser(UsageType.CPU, 1000, Pid.getPid());
ProcParser pp_Memory = new ProcParser(UsageType.MEMORY, 1000, Pid.getPid());
ProcParser pp_Disk = new ProcParser(UsageType.DISK, 1000, Pid.getPid());
ProcParser pp_Network = new ProcParser(UsageType.NETWORK, 1000, Pid.getPid());
ArrayList<String> cpuData = null;
ArrayList<String> memoryData = null;
ArrayList<String> diskData = null;
ArrayList<String> networkData = null;
pp_Cpu.start();
pp_Memory.start();
pp_Disk.start();
pp_Network.start();
for (;;) {
if (pp_Cpu.isReady() && pp_Memory.isReady()
&& pp_Disk.isReady() && pp_Network.isReady()) {
cpuData = pp_Cpu.getUsageData();
memoryData = pp_Memory.getUsageData();
diskData = pp_Disk.getUsageData();
networkData = pp_Network.getUsageData();
} else {
sleep(1000); //this does not work. I have to extend to Thread also the main class?
}
}
我如何不时偷看聚集的价值观?另外,从Java线程的角度来看,我正在创建线程(每个主要组件一个)的方法是一种好方法吗?提前谢谢。
在ProcParser中运行方法。
@Override
public void run() {
if ((this.usageType == null) || (this.sleepTime < 0) || (this.processPid < 0)) {
throw new IllegalArgumentException();
}
//Forever sleep and gather the usage values
for (;;) {
this.ready = false;
switch (this.usageType) {
case CPU:
this.gatherCpuUsage();
this.ready = true;
break;
case MEMORY:
this.gatherMemoryUsage(this.processPid);
this.ready = true;
break;
case DISK:
this.gatherDiskUsage();
break;
case NETWORK:
this.gatherNetworkUsage();
break;
case PARTITION:
this.gatherPartitionUsage();
break;
default:
break;
}
}
}
答案 0 :(得分:1)
我如何不时偷看收集的价值观?
我假设您的ProcParser
个线程在后台运行,从/proc
读取CPU数据(例如),然后休眠。您可能需要考虑使用AtomicReference
。如下所示:
private final AtomicReference<List<String>> cpuDataReference =
new AtomicReference<List<String>>();
...
ProcParser pp_Cpu =
new ProcParser(UsageType.CPU, 1000, Pid.getPid(), cpuDataReference);
...
// in your `ProcParser`
List<String> cpuDataList = new ArrayList<String>();
// read in the /proc files into the list
...
// save it in the AtomicReference passed into the constructor
dataReference.set(cpuDataList);
// other threads could then get the latest list
List<String> cpuDataList = cpuDataReference.get();
如果您担心消费者更改列表,您可能希望set()
是不可修改的列表。
从Java Threading的角度来看,我创建线程的方式(每个主要组件一个)是一种好的方法吗?
如果这不是一个练习,我会说你不需要线程的复杂性 - 它不会给你带来太大的影响。选择哪些任务需要一个线程,要创建多少线程等等,是在这些情况下需要做出的关键决策。
通常,您应该考虑ProcParser
实施Runnable
而不是扩展Thread
,然后说new Thread(new ProcParser(...))
。这是推荐的模式。您还应始终考虑使用ExecutorService
类返回的Executors
类。这些线程池接管线程的管理,使代码更简单。
答案 1 :(得分:0)
不要轮询is_ready
,而是查看Object.wait
和Object.notifyAll
。您可以使用ProcParser.waitUntilReady
编写Object.wait
方法,并使用Object.notifyAll
唤醒在工作线程生成结果时等待其准备就绪的所有线程。
或者,由于您的解析器正在生成项目列表,请查看java.util.concurrent
中的生产者使用者队列。