论坛网站太难做没人,全新的手机网站设计,免费ppt模板网站哪个好用,qq浏览器在线打开网页线程中断机制
概念
java提供了一种用于停止线程的协商机制-中断。称为中断标识协商机制。
常用API
public void interrupt() 仅仅让线程的中断标志位设置为true。不进行其他操作。public boolean isInterrupted() 获取中断标志位的状态。public static boolean interrupted…线程中断机制
概念
java提供了一种用于停止线程的协商机制-中断。称为中断标识协商机制。
常用API
public void interrupt() 仅仅让线程的中断标志位设置为true。不进行其他操作。public boolean isInterrupted() 获取中断标志位的状态。public static boolean interrupted() 获取中断标志位的状态。并将中断标志位设置为false
如何停止中断运行的线程
volatile变量实现
private static volatile boolean isStop false;public static void main(String[] args) {new Thread(() - {while (true) {if (isStop) {System.out.println(Thread.currentThread().getName() 线程isStop true,自己退出);break;}System.out.println(-------hello interrupt--------);}}, t1).start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}isStop true;}
AtomicBoolean实现
private static final AtomicBoolean atomicBoolean new AtomicBoolean(true);public static void main(String[] args) {new Thread(() - {while (atomicBoolean.get()) {try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(-------hello------);}}).start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}atomicBoolean.set(false);}
中断API interrupt和isInterrupted
public static void main(String[] args) {Thread t1 new Thread(() - {while (true) {if (Thread.currentThread().isInterrupted()) {System.out.println(-----t1 线程被中断了程序结束);break;}System.out.println(-----hello-------);}}, t1);t1.start();System.out.println(t1是否被中断 t1.isInterrupted());try {TimeUnit.MILLISECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}t1.interrupt();System.out.println(t1是否被中断 t1.isInterrupted());}
注意
如果线程处于正常活动状态interrupt会将该线程中断状态位设置为true。要想该线程进行进一步处理需要自己根据中断状态为来写业务逻辑。如果线程处于阻塞状态sleep, wait, join在别的线程调用当前线程interrupt方法那么线程立即退出阻塞状态并抛出InterruptException异常并将中断标志为清除置为false
Thread t1 new Thread(() - {while (true){if(Thread.currentThread().isInterrupted()){System.out.println(Thread.currentThread().getName()\t 中断标志位Thread.currentThread().isInterrupted() 程序停止);break;}try {Thread.sleep(200);} catch (InterruptedException e) {Thread.currentThread().interrupt();//为什么要在异常处再调用一次// 阻塞状态下的线程设置中断标志位为true,会报异常。中断状态位置为false。导致死循环。因此需要再次设置为truee.printStackTrace();}System.out.println(-----hello InterruptDemo3);}}, t1);t1.start();//暂停几秒钟线程try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }new Thread(() - t1.interrupt(),t2).start();拓展线程有哪些状态7种状态 创建就绪等待CPU运行阻塞(等待锁对象)等待等待事件超时等待结束 sleep不会释放锁。wait会释放锁。因此sleep进入等待状态。wait进入阻塞状态。
LockSupport
LockSupport是线程阻塞和唤醒的工具类。主要通过park阻塞和unpark唤醒。
线程等待唤醒机制
Synchronized锁对象的wait和notify
Object objectLock new Object();new Thread(() - {try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }synchronized (objectLock){System.out.println(Thread.currentThread().getName()\t ----come in);try {objectLock.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()\t ----被唤醒);}},t1).start();//暂停几秒钟线程//try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }new Thread(() - {synchronized (objectLock){objectLock.notify();System.out.println(Thread.currentThread().getName()\t ----发出通知);}},t2).start();限制
必须在Synchronized同步块中wait必须在之前notify。否则通知唤醒会失效。
Lock.condition的await和signal Lock lock new ReentrantLock();Condition condition lock.newCondition();new Thread(() - {try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }lock.lock();try{System.out.println(Thread.currentThread().getName()\t ----come in);condition.await();System.out.println(Thread.currentThread().getName()\t ----被唤醒);} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}},t1).start();//暂停几秒钟线程//try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }new Thread(() - {lock.lock();try{condition.signal();System.out.println(Thread.currentThread().getName()\t ----发出通知);}finally {lock.unlock();}},t2).start();LockSupport的park和unpark
Thread t1 new Thread(() - {try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println(Thread.currentThread().getName() \t ----come inSystem.currentTimeMillis());LockSupport.park();System.out.println(Thread.currentThread().getName() \t ----被唤醒System.currentTimeMillis());}, t1);t1.start();//暂停几秒钟线程//try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }new Thread(() - {LockSupport.unpark(t1);System.out.println(Thread.currentThread().getName()\t ----发出通知);},t2).start();优点
不需要在锁块中本身就可以让线程同步。park和unpark不需要有先后顺序。unpark相当于给了park一个凭证。unpark在park执行前也可以让park唤醒。相当于提前给了凭证。而前面两种就不行一个park需要一个凭证。但是不同的unpark作用于一个线程只能给一个凭证。即是连续调用多次unpark和调用一次作用是一样的