我如何不时地从线程中查看值?

时间:2012-05-08 19:00:15

标签: java multithreading proc

我正在用Java预测一个监控客户端,它将从/proc读取信息。我有一个主要课程MonitoringClientProcParser课程。我的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;
            }
        }
    }

2 个答案:

答案 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.waitObject.notifyAll。您可以使用ProcParser.waitUntilReady编写Object.wait方法,并使用Object.notifyAll唤醒在工作线程生成结果时等待其准备就绪的所有线程。

或者,由于您的解析器正在生成项目列表,请查看java.util.concurrent中的生产者使用者队列。