主线程结束不了,打上断点就结束,求解

qbw2010 2015-05-07 03:47:14

for (int i = 0; i < threadNum; i++)
{
Thread t = new WorkThread(apiName, param);
t.start();
}

// textArea.setText();
while(true)
{
if(!WorkThread.hasThreadRunning())
{
textArea.append("花费的时间为:" +(System.currentTimeMillis()-formerTime)+" millsecond \n");
break;
}
}


workThread.hasThreadRunning()代码如下:

public static boolean hasThreadRunning()
{
return (runningThreads.size()>0);
}


runningThreads结构中放的是线程本身.

现在出现的问题是运行程序后程序会死掉. 但是当在第一段代码的 if 语句中加入断点则程序就会正常.还有在while中加入
Thread.sleep(500); 程序也能正常.
问:1.为什么加入断点程序会正常? 2.为什么加入Thread.sleep(500);程序也会正常?
...全文
562 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
public_TIM 2018-01-02
  • 打赏
  • 举报
回复
while(true){} 不是死循环吗?主线程会一直运行下去,所以程序不会停止。
ΑΝΑГКН 2017-12-31
  • 打赏
  • 举报
回复
我也遇到了同样的问题 ,是while(true){} 的原因; http://blog.csdn.net/u012406012/article/details/52082503这里有较详细的解释。
qbw2010 2015-05-12
  • 打赏
  • 举报
回复
引用 7 楼 crazypandariy 的回复:
主线程M和在主线程中创建的线程S,两者都是线程,那么理论上他们是并行的。t.start()之后,S和M并行执行,如果M执行到!WorkThread.hasThreadRunning()的时候,S还未完成regist,那么就出现了你说的程序终止了。 其实就是cpu的时间分片的问题,就是M执行会儿,换S执行,就看谁运行的快了。 如果你就只有一个线程,根本没有必要使用synchronized。 如果你只是为了标志线程的个数,可以使用AtomicInteger进行+-,效率会高很多。 利用CountDownLatch完成你想要的结果:

public class WorkThread extends Thread{

	private  static List<Thread> runningThreads = new ArrayList<Thread>();
	private  ITest apiClass ;
	private  int  numberOfOperation;
	private CountDownLatch cdl;
	
	public WorkThread(String apiName, Map<String,Object> param,CountDownLatch cdl) throws Exception 
	{
		apiClass = (ITest)(Class.forName(apiName).newInstance());
		apiClass.set(param);
		this.numberOfOperation = Integer.parseInt(((String)param.get("numberOfOperation")));
		this.cdl = cdl;
	}
	
	public void regist(Thread t)
	{
		synchronized (runningThreads) {
			runningThreads.add(t);
		}
	}
	
	public void unregist(Thread t)
	{
		synchronized (runningThreads) {
			runningThreads.remove(t);
		}
	}
	
	public static boolean hasThreadRunning()
	{
		return (runningThreads.size()>0);
	}
	
	
	public void run()
	{
		regist(this);
		cdl.countDown();
		for(int i = 0 ; i<numberOfOperation; i++)
		{
			apiClass.run();
		}
			
		unregist(this);
		apiClass.release();
	}

}
修改后的调用代码:
		CountDownLatch cdl = new CountDownLatch(1);
		for (int i = 0; i < threadNum; i++) 
		{
			Thread t = new WorkThread(apiName, param,cdl);
			t.start();
		}
		cdl.await();
//		textArea.setText();
		while(true)
		{
			if(!WorkThread.hasThreadRunning())
			{
				textArea.append("花费的时间为:" +(System.currentTimeMillis()-formerTime)+" millsecond \n");
				break;
			}
		}
我知道你的意思Thread.sleep()是让主线程等一下再检查是否有线程运行,但是程序并没有出现这样的问题,而是假死了~~ 程序进不去if()代码块,放上断点后就能进去
疯狂熊猫人 2015-05-08
  • 打赏
  • 举报
回复
主线程M和在主线程中创建的线程S,两者都是线程,那么理论上他们是并行的。t.start()之后,S和M并行执行,如果M执行到!WorkThread.hasThreadRunning()的时候,S还未完成regist,那么就出现了你说的程序终止了。 其实就是cpu的时间分片的问题,就是M执行会儿,换S执行,就看谁运行的快了。 如果你就只有一个线程,根本没有必要使用synchronized。 如果你只是为了标志线程的个数,可以使用AtomicInteger进行+-,效率会高很多。 利用CountDownLatch完成你想要的结果:

public class WorkThread extends Thread{

	private  static List<Thread> runningThreads = new ArrayList<Thread>();
	private  ITest apiClass ;
	private  int  numberOfOperation;
	private CountDownLatch cdl;
	
	public WorkThread(String apiName, Map<String,Object> param,CountDownLatch cdl) throws Exception 
	{
		apiClass = (ITest)(Class.forName(apiName).newInstance());
		apiClass.set(param);
		this.numberOfOperation = Integer.parseInt(((String)param.get("numberOfOperation")));
		this.cdl = cdl;
	}
	
	public void regist(Thread t)
	{
		synchronized (runningThreads) {
			runningThreads.add(t);
		}
	}
	
	public void unregist(Thread t)
	{
		synchronized (runningThreads) {
			runningThreads.remove(t);
		}
	}
	
	public static boolean hasThreadRunning()
	{
		return (runningThreads.size()>0);
	}
	
	
	public void run()
	{
		regist(this);
		cdl.countDown();
		for(int i = 0 ; i<numberOfOperation; i++)
		{
			apiClass.run();
		}
			
		unregist(this);
		apiClass.release();
	}

}
修改后的调用代码:
		CountDownLatch cdl = new CountDownLatch(1);
		for (int i = 0; i < threadNum; i++) 
		{
			Thread t = new WorkThread(apiName, param,cdl);
			t.start();
		}
		cdl.await();
//		textArea.setText();
		while(true)
		{
			if(!WorkThread.hasThreadRunning())
			{
				textArea.append("花费的时间为:" +(System.currentTimeMillis()-formerTime)+" millsecond \n");
				break;
			}
		}
oh_Maxy 2015-05-08
  • 打赏
  • 举报
回复
hasThreadRunning方法里也对runningThreads加锁吧, 还有主方法while true前面一行加上个Thread.sleep(500),等半秒试试 还不行就发下ITest的源码,再深入分析下。
qbw2010 2015-05-08
  • 打赏
  • 举报
回复
发一下runningThreads的代码

public class WorkThread extends Thread{

	private  static List<Thread> runningThreads = new ArrayList<Thread>();
	private  ITest apiClass ;
	private  int  numberOfOperation;
	
	public WorkThread(String apiName, Map<String,Object> param) throws Exception 
	{
		apiClass = (ITest)(Class.forName(apiName).newInstance());
		apiClass.set(param);
		this.numberOfOperation = Integer.parseInt(((String)param.get("numberOfOperation")));
		
	}
	
	public void regist(Thread t)
	{
		synchronized (runningThreads) {
			runningThreads.add(t);
		}
	}
	
	public void unregist(Thread t)
	{
		synchronized (runningThreads) {
			runningThreads.remove(t);
		}
	}
	
	public static boolean hasThreadRunning()
	{
		return (runningThreads.size()>0);
	}
	
	
	public void run()
	{
		regist(this);
		for(int i = 0 ; i<numberOfOperation; i++)
		{
			apiClass.run();
		}
			
		unregist(this);
		apiClass.release();
	}

}
qbw2010 2015-05-08
  • 打赏
  • 举报
回复
引用 2 楼 scmod 的回复:
不是因为while(true)没结束条件么... 加上延时循环慢了就不卡了...
什么意思?当线程结束时自动remove出runningThread 当runningThread.size()==0时就退出
qbw2010 2015-05-08
  • 打赏
  • 举报
回复
引用 1 楼 oh_Maxy 的回复:
runningThreads 有没有做锁操作?初始的runningThreads.size()==0吧
有做锁操作: 开启一个线程时会使用runningThreads的内部锁, 然后把这个线程对象放到这个list列表里面.开始时runningThreads.size()是等于0的
scmod 2015-05-07
  • 打赏
  • 举报
回复
不是因为while(true)没结束条件么... 加上延时循环慢了就不卡了...
oh_Maxy 2015-05-07
  • 打赏
  • 举报
回复
runningThreads 有没有做锁操作?初始的runningThreads.size()==0吧

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧