0

我正在用 Java 投影一个监控客户端,它将从/proc. 我有一个主班MonitoringClientProcParser班。我的ProcParser扩展Thread

我认为这是实例化许多(四个:cpu、内存、磁盘和网络)ProcParser对象的好方法,传递我想在构造函数中测量的组件之一。然后,在 run 方法中,我在 then 之间切换 - 每个对象都会解析其中一个。代码将类似于:

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;
            }
        }
    }
4

2 回答 2

1

我如何不时查看收集的值?

我假设您的ProcParser线程在后台运行,从 读取 CPU 数据(例如)/proc,然后休眠。您可能要考虑使用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 线程的角度来看,我创建线程(每个主要组件一个)的方式是一种好方法吗?

如果这不是一个练习,我会说你不需要线程复杂性——它不会给你带来太多好处。选择哪些任务需要一个线程、创建多少个线程等是在这些情况下需要做出的关键决策。

通常,您应该考虑制作ProcParser实现Runnable而不是扩展Thread,然后说new Thread(new ProcParser(...)). 这是推荐的模式。您还应该始终考虑使用ExecutorService类返回的Executors类。这些线程池接管线程的管理并使您的代码更简单。

于 2012-05-08T19:20:45.197 回答
0

代替轮询is_ready,查看Object.waitand Object.notifyAll。您可以编写一个ProcParser.waitUntilReady方法 usingObject.wait和 useObject.notifyAll在工作线程产生结果时唤醒任何等待直到其准备就绪的线程。

或者,由于您的解析器正在生成项目列表,因此请查看java.util.concurrent.

于 2012-05-08T19:04:31.723 回答