IllegalThreadStateException: Thread already started解决
2016-04-05 15:26
537 查看
IllegalThreadStateException的原因解析
mThread = new MThread(); mThread.start(); mThread.interrupt(); mThread.start();
这段代码运行,就会出现上面的异常,从字面是理解也很容易理解:非法线程状态异常,线程已经start。
具体原因也很容易找到,看一下thread.start()里面做了什么:
public synchronized void start() { checkNotStarted(); hasBeenStarted = true; nativeCreate(this, stackSize, daemon); }
private void checkNotStarted() { if (hasBeenStarted) { throw new IllegalThreadStateException("Thread already started"); } }
在线程开始的时候会将hasBeenStarted设置成true,而在interrupt终止线程的时候,并没有将hasBeenStarted设置成false,所以在第二次start线程的时候会出现IllegalThreadStateException。
解决方法
new 一个新的threadthread不终止
对于第一个方法,创建新的线程去执行,这个方法不建议使用,因为大量的线程会影响你应用的性能,而第二个方法不终止线程,听起来可行,但是有一些具体情况,必须需要我们终止我们的线程,有没有一种情况是在一个线程里面我们想什么时候让它运行就什么时候运行,不运行的时候等待。答案是有的——PriorityBlockingQueue。
BlockingQueue | 抛出异常 | 特殊值 | 阻塞 | 超时 |
---|---|---|---|---|
插入 | add(e) | offer(e) | put(e) | offer(e,time,unit) |
移除 | remove() | pull() | take() | pull(time,unit) |
检查 | element() | peek() | 不可用 | 不可用 |
- offer(E e):表示如果可能的话,将e加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false。
- put(E e):把e加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续。
- take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到Blocking有新的对象被加入为止
其中take方法取值失败后:阻断进入等待状态直到Blocking有新的对象被加入为止。
private final PriorityBlockingQueue<Long> mQueue = new PriorityBlockingQueue<>(); mQueue.add(delayTime);
private class Dispatcher extends Thread { WeakReference<MainActivity> context; public Dispatcher(MainActivity activity) { context = new WeakReference<>( activity); } @Override public void run() { super.run(); long loadTime; while (true) { try { loadTime = mQueue.take(); } catch (Exception e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } if (context == null || context.get() == null) { return; } continue; } if (context == null || context.get() == null) { return; } if (isStop.get()) { return; } int i = mProgressBar == null ? 0 : mProgressBar.getProgress(); for (; i < 100; ) { if (isStop.get()) { return; } if (context == null || context.get() == null) { return; } i += ratio; } } } }
mQueue.take()取值失败后会阻塞,当我们需要线程开始运行的时候,只要向队列里面add值就可以了
相关文章推荐
- CCF 窗口
- .so的封装调用
- wifidog 源码初分析(一)
- 接口传值的收藏!
- [FractionalProgramming]分数规划
- FFmpeg在iOS上完美编译
- .so的封装调用
- Git- Fatal: cannot do a partial commit during a merge
- Android的Binder机制概念介绍
- DRM初始化过程
- redis、memcached
- JVM-字节码执行引擎
- iOS--独立开发的相关
- C# 命名规范
- 写完代码再写诗,是多么陶醉~
- 解析xml
- 写完代码再写诗,是多么陶醉~
- Initialization of variable was never used; consider replacing with assignment to ‘_’ or removing it
- 设计模式-策略模式 java实现
- 我的第一篇博客