在Linux下多线程的问题
最近做的程序出现了一个多线程的问题,肯定是同步引起的,但是我个人还是不太理解,因为同样一段代码在Windows下运行正常,在Linux下就处理一堆问题了。
程序思想是这样子的,有多个任务需要处理,每次主线程处理一个任务,并把这个任务分成多个子任务让子线程去处理。在主线程中启动多个子线程去做事情,并注册自己。主线程就不断的检查是所有线程已经注销了,子线程做完事情后,会向主线程销自己,然后结束。
代码如下:
public class TaskDispatchController { Set threadSet = new HashSet(); /** * 启动子线线程做事情 */ private void startThread() { //重用线程对象 ImportThread[] thread = importTool.getImportThread(); threadList = new ArrayList(thread.length); for (int i = 0; i < thread.length; i++) { ImportThread impThread = thread[i]; //子线程注册自己 threadSet.add(impThread); impThread.setController(this); new Thread(impThread).start(); } checkQuite(); } /** * 注销自己,并唤醒主线程检查是否可以退出 */ public synchronized void unregister(ImportThread thread) { threadSet.remove(thread); notifyAll(); } /** * */ private synchronized void checkQuite() { try { while (!threadSet.isEmpty()) { wait(); } backThread(); } catch (InterruptedException e) { throw new ThreadOperationException("main thread exception", e); } finally { close(); } } } public class ImportThread { TaskDispatchController taskDispatchController = null; public void setController(TaskDispatchController taskDispatchController ) { this.taskDispatchController = taskDispatchController ; } public void run() { if (taskDispatchController == null) { return; } //做某事情 [b]taskDispatchController.doXXX();[/b] while (true) { // do something } //执行完事情后结束 release(); } private void release() { if (taskDispatchController != null) { taskDispatchController .unregister(this); } [b]taskDispatchController == null;[/b] } }
这段代码在Windows下,双核CPU的环境中做事不会出现错误,且可以启动多个子线程。但在Linux环境下,就启动一个子线程就会出问题,会出现死锁,并且是销在TaskDispatchController的startThread方法,感到很奇怪。
解决方法:随后,我将startThread线程,并标记为同步,并且要所有子线程启动后,子线程才能注销自己。以避免子线程跑得太快了,就结束自己了(这是领导认为的问题所在,但我个人不这么认为,看代码就明白了)。
修改了之后仍然出现死锁。原因是:在子线程run中调用taskDispatchController.doXXX()的时候报NullPointerException,导致子线程没有注销自己,主线程处于一直等待状态。
解决方法:因为我在线程结束的时候将taskDispatchController = null了(也不知道当时是怎么考虑的,其实没有必要设置为null),所以我将release方法中这一行删去。
并修改TaskDispatchController.unregister方法
public synchronized void unregister(ImportThread thread) { threadSet.remove(thread); thread.setController(null); notifyAll(); }
现在程序在Linux下能正常运行,但其中的原因还是不得而知,希望哪位指点指点
dennis_zane
2008-09-11
同步后出现的空指针问题,想了下,我的理解还是错误,也没有复现你的场景。你说“并且要所有子线程启动后,子线程才能注销自己”,不知道怎么修改的,我想看看,可能是你修改的部分出问题了。
dennis_zane
2008-09-11
卒子99
2008-09-12
我是加了一个变量 来控制的
相关文章:
你感兴趣的文章:
标签云: