IllegalThreadStateException: Thread already started解决

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 一个新的thread
  • thread不终止

对于第一个方法,创建新的线程去执行,这个方法不建议使用,因为大量的线程会影响你应用的性能,而第二个方法不终止线程,听起来可行,但是有一些具体情况,必须需要我们终止我们的线程,有没有一种情况是在一个线程里面我们想什么时候让它运行就什么时候运行,不运行的时候等待。答案是有的——PriorityBlockingQueue。

BlockingQueue抛出异常特殊值阻塞超时
插入add(e)offer(e)put(e)offer(e,time,unit)
移除remove()pull()take()pull(time,unit)
检查element()peek()不可用不可用

- add(E e):把e加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则招聘异常。
- 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值就可以了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值