java 控制器如何实现_java线程控制器实现(转)

在人人网海量存储系统的存储引擎部分,为了提高CPU和网络的使用情况,使用了java多线程管理并行操作的方式。

在java中控制线程是一件很简单的事情,jdk提供了诸多的方法,其中比常用的两个是notify()和wait(),一个是唤醒,一个等待线程,在下面的代码中,将看到一个线程分配器,根据cpu的负载情况,自动完成对应线程的唤醒或者是等待操作。整个过程是一个平滑的过程,不会因为线程的切换而导致机器负载出线锯齿。

先看一个类,读取Linux系统TOP等指令拿到系统当前负载:importjava.io.BufferedReader;importjava.io.InputStreamReader;/*** 节点的cpu 内存 磁盘空间 情况

*

*@authorzhen.chen

**/publicclassNodeLoadView {/*** 获取cpu使用情况

*

*@return*@throwsException*/publicdoublegetCpuUsage()throwsException {doublecpuUsed=0;

Runtime rt=Runtime.getRuntime();

Process p=rt.exec(“/usr/bin/uptime”);//调用系统的“top”命令String[] strArray=null;

BufferedReader in=null;try{

in=newBufferedReader(newInputStreamReader(p.getInputStream()));

String str=null;while((str=in.readLine())!=null) {

strArray=str.split(“load average: “);

strArray=strArray[1].split(“,”);

cpuUsed=Double.parseDouble(strArray[0]);

}

}catch(Exception e) {

e.printStackTrace();

}finally{

in.close();

}returncpuUsed;

}/*** 内存监控

*

*@return*@throwsException*/publicdoublegetMemUsage()throwsException {doublemenUsed=0;

Runtime rt=Runtime.getRuntime();

Process p=rt.exec(“top-b-n1″);//调用系统的“top”命令BufferedReader in=null;try{

in=newBufferedReader(newInputStreamReader(p.getInputStream()));

String str=null;

String[] strArray=null;while((str=in.readLine())!=null) {intm=0;if(str.indexOf(” R “)!=-1) {//只分析正在运行的进程,top进程本身除外 &&System.out.println(“——————3—————–”);strArray=str.split(” “);for(String tmp : strArray) {if(tmp.trim().length()==0)continue;if(++m==10) {//9)–第10列为mem的使用百分比(RedHat 9)menUsed+=Double.parseDouble(tmp);

}

}

}

}

}catch(Exception e) {

e.printStackTrace();

}finally{

in.close();

}returnmenUsed;

}/*** 获取磁盘空间大小

*

*@return*@throwsException*/publicdoublegetDeskUsage()throwsException {doubletotalHD=0;doubleusedHD=0;

Runtime rt=Runtime.getRuntime();

Process p=rt.exec(“df-hl”);//df -hl 查看硬盘空间BufferedReader in=null;try{

in=newBufferedReader(newInputStreamReader(p.getInputStream()));

String str=null;

String[] strArray=null;while((str=in.readLine())!=null) {intm=0;//if (flag > 0) {//flag++;strArray=str.split(” “);for(String tmp : strArray) {if(tmp.trim().length()==0)continue;++m;//System.out.println(“—-tmp—-” + tmp);if(tmp.indexOf(“G”)!=-1) {if(m==2) {//System.out.println(“—G—-” + tmp);if(!tmp.equals(“”)&&!tmp.equals(“0″))

totalHD+=Double.parseDouble(tmp.substring(0,

tmp.length() –1))*1024;

}if(m==3) {//System.out.println(“—G—-” + tmp);if(!tmp.equals(“none”)&&!tmp.equals(“0″))

usedHD+=Double.parseDouble(tmp.substring(0,

tmp.length() –1))*1024;

}

}if(tmp.indexOf(“M”)!=-1) {if(m==2) {//System.out.println(“—M—” + tmp);if(!tmp.equals(“”)&&!tmp.equals(“0″))

totalHD+=Double.parseDouble(tmp.substring(0,

tmp.length() –1));

}if(m==3) {//System.out.println(“—M—” + tmp);if(!tmp.equals(“none”)&&!tmp.equals(“0″))

usedHD+=Double.parseDouble(tmp.substring(0,

tmp.length() –1));//System.out.println(“—-3—-” + usedHD);}

}

}//}}

}catch(Exception e) {

e.printStackTrace();

}finally{

in.close();

}return(usedHD/totalHD)*100;

}public static void main(String[] args) throws Exception {//NodeLoadView cpu = new NodeLoadView();//System.out//.println(“—————cpu used:” + cpu.getCpuUsage() + “%”);//System.out//.println(“—————mem used:” + cpu.getMemUsage() + “%”);//System.out//.println(“—————HD used:” + cpu.getDeskUsage() + “%”);//System.out.println(“————jvm监控———————-”);//Runtime lRuntime = Runtime.getRuntime();//System.out.println(“————–Free Momery:” + lRuntime.freeMemory()//+ “K”);//System.out.println(“————–Max Momery:” + lRuntime.maxMemory()//+ “K”);//System.out.println(“————–Total Momery:”//+ lRuntime.totalMemory() + “K”);//System.out.println(“—————Available Processors :”//+ lRuntime.availableProcessors());//}}

再来看关键的一个类,THreadScheduler:importjava.util.Map;importorg.apache.log4j.Logger;importtest.NodeLoadView;publicclassThreadScheduler {privatestaticLogger logger=Logger.getLogger(ThreadScheduler.class.getName());privateMaprunningThreadMap;privateMapwaitingThreadMap;privatebooleanisFinished=false;privateintrunningSize;publicThreadScheduler (MaprunningThreadMap, MapwaitingThreadMap) {this.runningThreadMap=runningThreadMap;this.waitingThreadMap=waitingThreadMap;this.runningSize=waitingThreadMap.size();

}/*** 开始调度线程

*@authorzhen.chen

* @createTime 2010-1-28 上午11:04:52*/publicvoidschedule(){longsleepMilliSecond=1*1000;intallowRunThreads=15;//一次启动的线程数,cpuLoad变大时以此值为参考递减intallowRunThreadsRef=15;doublecpuLoad=0;//0-15NodeLoadView load=newNodeLoadView();while(true) {try{

cpuLoad=load.getCpuUsage();

}catch(Exception e1) {

e1.printStackTrace();

}//cpuLoad低 启动的线程多allowRunThreads=(int) Math.floor(allowRunThreadsRef – cpuLoad);//threads不能为0if(allowRunThreads<1) {

allowRunThreads=1;

}if(allowRunThreads>allowRunThreadsRef) {

allowRunThreads=allowRunThreadsRef;

}if(logger.isDebugEnabled()) {

logger.debug(“[ThreadScheduler]running Thread:”+runningThreadMap.size()+“; waiting Thread:”+waitingThreadMap.size()+“; cpu:”+cpuLoad+” allowRunThreads:”+allowRunThreads);

}//检查runningSize个线程的情况,满足条件则启动for(intx=0; x

}synchronized(waitingThreadMap.get(x+”")) {if(!waitingThreadMap.get(x+”").isAlive()) {waitingThreadMap.get(x+”").start();}else{

waitingThreadMap.get(x+”").notify();}

}

runningThreadMap.put(x+”", waitingThreadMap.get(x+”"));

waitingThreadMap.remove(x+”");}

}//检查runningSize个线程的情况,满足条件则暂停for(intx=0; x

}if(runningThreadMap.get(x+”") != null) {synchronized(runningThreadMap.get(x+”")) {try{if(runningThreadMap.get(x+”").isAlive()) {runningThreadMap.get(x+”").wait();}else{continue;

}

}catch(InterruptedException e) {

e.printStackTrace();

}

}

waitingThreadMap.put(x+”", runningThreadMap.get(x));runningThreadMap.remove(x+”");}

}//全部跑完,返回if(waitingThreadMap.size()==0&&runningThreadMap.size()==0) {if(logger.isDebugEnabled()) {

logger.debug(“[ThreadScheduler] over.total Threads size:”+runningSize);

}this.isFinished=true;return;

}//使主while循环慢一点try{

Thread.sleep(sleepMilliSecond);

}catch(InterruptedException e1) {

e1.printStackTrace();

}

}

}publicbooleanisFinished() {returnisFinished;

}

}

这个类的作用:1.接收runningThreadMap和waitingThreadMap两个map,里面对应存了运行中的线程实例和等待中的线程实例。2.读cpu情况,自动判断要notify等待中的线程还是wait运行中的线程。3.两个map都结束,退出。(必须runningThreadMap内部的Thread自己将runningThreadMap对应的Thread remove掉)

如何使用:publicclassTestThread {publicstaticclassRunnerextendsThread {publicRunner(intj, MapthreadMap) {

}publicvoidrun() {//TODO 你的逻辑 完成后需要从threadMap中remove掉}

}publicstaticvoidmain(String[] args) {//运行中的线程MapthreadMap=newHashMap();//正在等待中的线程MapwaitThreadMap=newHashMap();for(intj=0; j

Thread t=newRunner(j, threadMap);

waitThreadMap.put(j+“”, t);

}

ThreadScheduler threadScheduler=newThreadScheduler(threadMap, waitThreadMap);

threadScheduler.schedule();if(threadScheduler.isFinished()==false) {//没能正常结束}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值