读书人

java 多线程的一个例证二

发布时间: 2012-10-27 10:42:25 作者: rapoo

java 多线程的一个例子二

前文实现的是通过一个主进程进行轮训的方式,这篇文章是采用的是线程自己控制依赖他的线程的新、运行方式。废话不说,贴上代码

xml的解析代码没有改动。主要是贴的是Thread的代码

package com.simple2;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Random;public class MyThread extends Thread {private static Map<MyThread,String> session = new HashMap<MyThread,String>();//进行lock的Sessionprivate static String[] lockSession = new String[10];private int account;public MyThread(){}public int getAfterCount(){return this.account;}public void setAfterCount(int count){this.account = count;}public void subAfterCount(){this.account--;}public static void initStaticDomain(){produceLockSession();initSession();}//初始化随机数private static void initSession(){List<ThreadEntity> threadlist = ThreadList.getThreadlist();for(int i = 0;i < threadlist.size();i++){session.put(threadlist.get(i).getProcess(), lockSession[i]);}}private static void produceLockSession(){String source = "abcdefghijklmnopqrstuvwxyz";String[] lockSession = MyThread.getLockSession();Random random = new Random();for(int i = 0;i < lockSession.length;i++){StringBuilder builder = new StringBuilder();//begin to generate a random string which of length is 5for(int j = 0;j < 5;j++){int position = random.nextInt(source.length());builder.append(source.charAt(position));}String temp = builder.toString();//判断生成的string 是否重复for(int j = 0;j < lockSession.length;j++){String curr = lockSession[i];if(curr == null || curr.length() == 0){lockSession[i] = temp;}else if(curr.equals(temp)){//有重复的再次生成;i--;break;}else{//不重复,比较下一个continue;}}}}public static String[] getLockSession() {return lockSession;}public static void setLockSession(String[] lockSession) {MyThread.lockSession = lockSession;}private void preProcess(){if(this.account != 0){String lock = session.get(this);synchronized (lock) {try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}//对象进行初始化的时候进行,否则会发生死锁public void initAccount() {List<ThreadEntity> threadlist = ThreadList.getThreadlist();for(ThreadEntity then : threadlist){if(then.getProcess() == this){//设置account的值setAfterCount(then.getPreEntities().size());break;}}}//运行完毕之后private void notifyAfter(){List<ThreadEntity> threadlist = ThreadList.getThreadlist();for(ThreadEntity te : threadlist){//依赖currentThread 的ThreadEntity subAfterCountfor(Map.Entry<Integer, ThreadEntity> entry:te.getPreEntities().entrySet()){MyThread thread = entry.getValue().getProcess();if(thread == this){te.getProcess().subAfterCount();}}//如果te代表的Thread subAfount为零,则开始将该进程的状态由wait变成runif(te.getProcess().getAfterCount() == 0){String lock = session.get(te.getProcess());synchronized (lock) {try {lock.notify();} catch (Exception e) {e.printStackTrace();}}}}}@Overridepublic void run() {try {//保证我们的所有的线程启动的时间在别的线程完成的时间前Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}preProcess();realRun();notifyAfter();}private void realRun() {List<ThreadEntity> threadlist = ThreadList.getThreadlist();for(ThreadEntity then : threadlist){if(then.getProcess() == this){System.out.println("current running Thread ID :" + then.getThreadID());}}}}

?Entity的代码没有什么改变,只是参数process改为MyThread

代码如下

package com.simple2;import java.util.HashMap;import java.util.Map;import com.simple2.ThreadEntity;public class ThreadEntity {private  Integer threadID;private Map<Integer,ThreadEntity> preEntities;private MyThread process;private boolean ready = false;public ThreadEntity(){preEntities = new HashMap<Integer, ThreadEntity>();    process = new MyThread();}public Integer getThreadID() {return threadID;}public void setThreadID(Integer threadID) {this.threadID = threadID;}public Map<Integer, ThreadEntity> getPreEntities() {return preEntities;}public void setPreEntities(Map<Integer, ThreadEntity> preEntities) {this.preEntities = preEntities;}public MyThread getProcess() {return process;}public void setProcess(MyThread process) {this.process = process;}public boolean isReady() {return ready;}public void setReady(boolean ready) {this.ready = ready;}public void addPreEntity(ThreadEntity te) {this.preEntities.put(te.getThreadID(), te);}}

?由上文我们可以知道,MyThread 创建对象的时候就对static 的对象尽心初始化,会造成初始化的error,这个是因为,MyThread 依赖 Threadlist ,但是Threadlist设置threadlist的时候,正好也是依赖MyThread,我只有先对MyThread进行初始化,然后再设置threadlist。

所以说,MyThread? static 里的成员,最好等threadlist初始化之后,在进行初始化。所以说,他们的生命周期需要向后推迟。还有当我们对account进行初始化的时候,不能在线程启动之后之后进行初始化。但是account又依赖于threadlist,所以说,account 也是不能在对象初始化的时候进行初始化,也是将生命周期延后。所以说,threadlist的代码如下

package com.simple2;import java.util.List;/** * 描述: * @author tippy * @date 2011-5-15 */public class ThreadList {private static List<ThreadEntity> threadlist;public static List<ThreadEntity> getThreadlist() {return threadlist;}public static void setThreadlist(List<ThreadEntity> threadList) {threadlist = threadList;}public static void startProcess(){for(ThreadEntity then:threadlist){then.getProcess().initAccount();then.getProcess().start();}}}

? 我用junit测试的时候,犹如,一个test运行完成之后,就认为测试完成,所以别的线程的测试结果总是无法显示,所以使用main进行测试

public static void main(String[] args) throws Throwable {
??? ??? ThreadList.setThreadlist(SimpleParse2.parseSimpleXML());
??? ??? MyThread.initStaticDomain();
??? ??? ThreadList.startProcess();
??? }

读书人网 >编程

热点推荐