Java多线程——中断
2016-04-08 10:56
435 查看
中断相关的方法Interrupt isInterrupt interrupted
进行中断
中断阻塞
作用:检测中断标志,并不会清空。返回是否中断,中断为true,未中断为false
静态方法interrupted()
作用:检测中断标志,并清空中断标志。返回是否中断,中断为true,未中断为false
使用thread.interrupt()方法 。使线程在可中断阻塞中抛出InterruptException()
关闭相应的资源。使得IO阻塞抛出相应的IOException()
循环检测中断标志
使用thread.interrupt()设置中断标志,并且在循环中使用thread.isInterrupted()或者Thread.interrupted()方法检查中断标志
使用自定义标记(flag)来控制是否中断,需要在循环中判断(flag)
如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的
join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int)
方法过程中受阻,则其isInterrupt状态将被清除,设成false, 它还将收到一个InterruptedException.
如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的isInterrupt状态将被设置成true, 并且该线程将收到一个ClosedByInterruptException。
等待锁释放,而被阻塞。使用ReentrantLock,可以时锁被中断
与前面在不可中断的I/O中所看到的一样,无论在任何时刻,只要任务以不可中断的方式被阻塞,那么都有潜在的会锁住程序的可能。Java SE5并发类库中添加了一个特性,即在ReentrantLock上阻塞的任务具备可以被中断的能力:.
不可中断的线程阻塞(无法通过interrupt中断)
等待锁释放,而被阻塞
一般的锁都是不可以中断的,所以在需要中断的线程中应该使用Reentrantlock
使用了不可中断的I/O
虽然不可以通过interrupt方法中断,但是可以通过关闭相应的资源,使线程抛出相应的IO异常,从而可以中断线程
进行中断
中断阻塞
中断相关的方法(Interrupt, isInterrupt, interrupted)
成员方法isInterrupt()作用:检测中断标志,并不会清空。返回是否中断,中断为true,未中断为false
public boolean isInterrupted() { return isInterrupted(false); } private native boolean isInterrupted(boolean ClearInterrupted);
静态方法interrupted()
作用:检测中断标志,并清空中断标志。返回是否中断,中断为true,未中断为false
public static boolean interrupted() { return currentThread().isInterrupted(true); } private native boolean isInterrupted(boolean ClearInterrupted);
进行中断
通过让线程抛出异常中断线程使用thread.interrupt()方法 。使线程在可中断阻塞中抛出InterruptException()
关闭相应的资源。使得IO阻塞抛出相应的IOException()
循环检测中断标志
使用thread.interrupt()设置中断标志,并且在循环中使用thread.isInterrupted()或者Thread.interrupted()方法检查中断标志
使用自定义标记(flag)来控制是否中断,需要在循环中判断(flag)
中断阻塞
可中断的线程阻塞如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的
join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int)
方法过程中受阻,则其isInterrupt状态将被清除,设成false, 它还将收到一个InterruptedException.
public void run() { while (true) { try{ Thread.sleep(1000); } catch (InterruptedException ie){ ie.printStackTrace(); return; } } }
如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的isInterrupt状态将被设置成true, 并且该线程将收到一个ClosedByInterruptException。
class NIOBlocked implements Runnable { private final SocketChannel sc; public NIOBlocked(SocketChannel sc){ this.sc = sc; } public void run() { try{ System.out.println("Waiting for read() in " + this); sc.read(ByteBuffer.allocate(1)); //进入阻塞 } catch(ClosedByInterruptException e) { System.out.println("ClosedByInterruptException"); } catch(AsynchronousCloseException e) { System.out.println("AsynchronousCloseException"); } catch(IOException e) { throw new RuntimeException(e); } System.out.println("exiting NIOBlocked.run() " + this); } } public class NIOInterruption{ public static void main(String[] args) throws IOException, InterruptedException { ExecutorService exec = Executors.newCachedThreadPool(); InetSocketAddress isa = new InetSocketAddress("localhost", 8080); SocketChannel sc1 = SocketChannel.open(isa); SocketChannel sc2 = SocketChannel.open(isa); Future<?> f = exec.submit(new NIOBlocked(sc1)); exec.execute(new NIOBlocked(sc2)); //sc1,sc2相互等待对方发送信息,进入阻塞死循环 exec.shutdown(); TimeUnit.SECONDS.sleep(1); f.cancel(true); //中止任务,中断阻塞 TimeUnit.SECONDS.sleep(1); sc2.close(); //关闭资源,中断阻塞 } }
等待锁释放,而被阻塞。使用ReentrantLock,可以时锁被中断
与前面在不可中断的I/O中所看到的一样,无论在任何时刻,只要任务以不可中断的方式被阻塞,那么都有潜在的会锁住程序的可能。Java SE5并发类库中添加了一个特性,即在ReentrantLock上阻塞的任务具备可以被中断的能力:.
class BlockedMutex{ private Lock lock = new ReentrantLock(); public BlockedMutex() { // 构造函数 立刻加锁 lock.lock(); } public void f() { try{ //此处将永远无法执行到 lock.lockInterruptibly(); System.out.println("lock acquired in f()"); } catch(InterruptedException e) { System.out.println("Interrupted from lock acquisition in f()"); } } } class Blocked2 implements Runnable { BlockedMutex blocked = new BlockedMutex(); //构造出BlockedMutex public void run() { System.out.println("Waiting for f() in BlockedMutex"); blocked.f(); System.out.println("Broken out of blocked call"); } } public class Interrupting2 { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new Blocked2()); t.start(); TimeUnit.SECONDS.sleep(1); System.out.println("Issuing t.interrupt()"); t.interrupt(); //中断阻塞 } }
不可中断的线程阻塞(无法通过interrupt中断)
等待锁释放,而被阻塞
一般的锁都是不可以中断的,所以在需要中断的线程中应该使用Reentrantlock
class SynchronizedBlocked implements Runnable { public synchronized void f() { while(true) { Thread.yield(); //方法f加锁后不再释放锁 } } public SynchronizedBlocked() { new Thread() { public void run(){ f(); // 这个类构造时f就加锁了,进入阻塞状态 } }.start(); } public void run(){ System.out.println("Trying to call f() "); f(); //没有机会执行 System.out.println("Exiting SynchronizedBlocked.run()"); } }
使用了不可中断的I/O
虽然不可以通过interrupt方法中断,但是可以通过关闭相应的资源,使线程抛出相应的IO异常,从而可以中断线程
class IOBlocked implements Runnable { private InputStream in; public IOBlocked(InputStream is){ in = is; } public void run(){ try{ System.out.println("Waiting for read();"); in.read(); //调用read方法,进入IO阻塞 } catch(IOException e) { if(Thread.currentThread().isInterrupted()) { System.err.println("Interrupted from blocked I/O"); } else { throw new RuntimeException(e); } } } }
相关文章推荐
- JAVA设计模式--工厂模式
- eclipse安装Run-Jetty-Run插件,修改实时生效
- org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cxf' is defined
- eclipse中批量修改java文件package路径
- Map对象的浅拷贝与深拷贝
- HashMap源码注解 之 成员变量(二)
- Java连接SAP ————JCO 3.0技术详解
- JDK 1.5 新特性之枚举值与枚举类
- Spring 注解
- 【Java并发编程五】信号量
- HashMap源码注解 之 常量定义(一)
- 深入理解Java:类加载机制及反射
- Eclipse jar打包和命令行运行
- 基于注解的Spring MVC的URL与Controller映射关系提取的实现分析
- C#调用java类、jar包方法
- JAVA中String.split()解析字符串的一点细节
- SpringMVC拦截器(资源和权限管理)
- HashMap和HashSet的区别
- 【Java集合源码剖析】Hashtable源码剖析
- java 项目域名解析