Java多线程实践之—终结
来源:互联网 发布:dnf修改时装软件 编辑:程序博客网 时间:2024/05/16 19:41
这一节学习线程的终结
1. 终结
(1)线程终结的情况:线程死亡的一正常方式是从run()方法返回,但是线程还可以被中断!
(2)阻塞的情况?
先了解下什么情况下一个线程将会进入阻塞状态:
1)通过调用sleep()方法,进入休眠状态;
2)通过调用wait()方法,直到notify()或notifyAll()消息【java.util.concurrent类库中的signal()和signalAll()】;
3)等待某个输入/ 输出完成;
4)在同步对象上调用其同步控制方法,但是对象锁不可用,因为另一个线程已经获得锁。
(3)中断
在run()方法中间打断(设置中断标志)线程运行,会抛出异常(异常抛出后,中断标志位复位)。Thread.interrupted()提供了离开run()循环而不抛出异常的第二种方法。为了调用interrupted(),必须先持有Thread对象,但是在concurrent类库中,似乎在避免对Thread的直接操作,转而使用Executors来执行所有操作。在Executors上调用shutdownNow(),那么它将发送一个interrupt()调用给它启动的所有线程。但是当你想要中断某一任务时,只能通过submit()而不是execute()来启动任务,submit将返回一个泛型Future<?>(与Callable接口不同,这里不需要调用get()方法),然后可以再Future上调用cancel()方法,将true传递给cancel,那么它将会调用interrupt()来停止这个线程。贴上代码,在分析!
package zy.thread.demo;import java.io.IOException;import java.io.InputStream;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;public class Interrupting {private static ExecutorService exec = Executors.newCachedThreadPool();static void test(Runnable r) throws InterruptedException {Future<?> future = exec.submit(r);TimeUnit.MILLISECONDS.sleep(100);System.out.println("Interrupting " + r.getClass().getName());future.cancel(true);System.out.println("Interrup sent to " + r.getClass().getName());}public static void main(String[] args) throws InterruptedException {test(new SleepBlocked());test(new IOBlocked(System.in));test(new SynchronizedBlocked());TimeUnit.SECONDS.sleep(3);System.out.println("Aborting with System.exit(0)");System.exit(0);}}class SleepBlocked implements Runnable {@Overridepublic void run() {try {TimeUnit.SECONDS.sleep(100);} catch (InterruptedException e) {System.out.println("InterruptedException");}System.out.println("Exiting SleepBlocked.run()");}}class IOBlocked implements Runnable {private InputStream in;public IOBlocked(InputStream in) {this.in = in;}@Overridepublic void run() {try {System.out.println("Waiting for read():");in.read();} catch (IOException e) {if (Thread.currentThread().isInterrupted())System.out.println("Interrupted from blocked I/O");elsethrow new RuntimeException(e);}System.out.println("Exiting IOBlocked.run()");}}class SynchronizedBlocked implements Runnable {public synchronized void f() {while (true)Thread.yield();}public SynchronizedBlocked() {new Thread() {public void run() {f();}}.start();}@Overridepublic void run() {System.out.println("Trying to call f()");f();System.out.println("Exiting SynchronizedBlocked.run()");}}Output : 95%匹配(5%是因为,SleepBlocked执行结果顺序无法预测)
分析:I/O和synchronized块上的等待不能被中断,那怎么办呢?在I/O上的阻塞,可以关闭任务在其上发生阻塞的底层资源:
package zy.thread.demo;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.*;public class CloseResource {public static void main(String[] args) throws Exception {ExecutorService exec = Executors.newCachedThreadPool(); ServerSocket server = new ServerSocket(8080); InputStream socketInput = new Socket("localhost", 8080).getInputStream(); exec.execute(new IOBlocked(socketInput)); exec.execute(new IOBlocked(System.in)); TimeUnit.MILLISECONDS.sleep(100); System.out.println("Shutting down all threads"); exec.shutdownNow(); TimeUnit.SECONDS.sleep(1); System.out.println("Closing " + socketInput.getClass().getName()); socketInput.close(); TimeUnit.SECONDS.sleep(1); System.out.println("Closing " + System.in.getClass().getName()); System.in.close();}}synchronized方法或临界区上的阻塞不可中断,但是ReentranLock上的阻塞则可以:
package zy.thread.demo;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;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();}}class BlockedMutex { private Lock lock = new ReentrantLock(); public BlockedMutex() { lock.lock(); } public void f() { try { // This will never be available to a second task lock.lockInterruptibly(); // Special call 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(); public void run() { System.out.println("Waiting for f() in BlockedMutex"); blocked.f(); System.out.println("Broken out of blocked call"); }}
下一篇:线程的协作!
0 0
- Java多线程实践之—终结
- Java多线程之终结任务
- Java多线程 之 终结任务(十一)
- java中的多线程终结
- Java多线程实践之—同步篇
- Java多线程实践之—协作
- Java NIO——4 在多线程环境下的恶梦之终结
- windows 多线程之终结线程
- Java多线程实践—篇外篇
- Java多线程实践之基础篇
- java多线程系列----------- 终结任务(一)
- java多线程系列----------- 终结任务(二)
- java 多线程 终结任务 装饰性花园
- Java并发之终结任务
- Java实践之路——多线程之生产者消费者模型
- java多线程与并发之java并发编程实践(一)
- java多线程与并发之java并发编程实践(二)
- java多线程与并发之java并发编程实践(三)
- Ubuntu14.04 安装 Oracle 11g R2 Express Edition
- ubuntu安装好后 ssh进入出错 access denied
- 上蓝翔
- hadoop2.7.1+nutch2.3+mongodb+solr5.2.1的单机配置
- 【JavaScript】BOM和DOM
- Java多线程实践之—终结
- johari窗口
- Mac osx 删除云梯VPN 配置文件(remove profiles)
- 关于大表consume的分表想法
- Java深度历险(六)——Java注解 2015.8.18
- 1001 - Say Cheese (Dijkstra算法)
- Oracle 中查看用户建立的所有触发器
- 基于java的挖地雷游戏
- Activity 生命周期