java 线程开启 中断
1.cpu时间片轮转机制
计算机运行时需要同时运行多个程序,但一个cpu只能同时运行一个程序,为了让用户感觉同时多个程序都在运行,需要模拟并行运算,就引入cpu时间片轮转机制。
操作系统一般是按照一定策略,定期给每个活动的进程执行其内部程序的机会,并且每次只执行一小段时间,然后操作系统利用中断强行退出执行,将当前程序信息压栈,然后开始执行下一个进程的一小段程序,通过这样不断快速的循环切换,每个程序都获得执行。(上下文切换)
在我们程序员看来,只需要理解程序是被操作系统片段执行的,每个片段就是一个时间片,在自己的程序运行时不是独一无二的,我们看似很顺畅的工作,其实是由一个个的执行片段构成的,我们眼中相邻的两条语句甚至同一个语句中两个不同的运算符之间,都有可能插入其他线程或进程的动作。
2.java线程
创建线程
package com.ljj.study; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class MyThread { private static class ExtendThread extends Thread { @Override public void run() { System.out.println("ExtendThread running "); System.out.println("id: " + Thread.currentThread().getId()); } } private static class RunThread implements Runnable { public void run() { System.out.println("RunThread running "); System.out.println("id: " + Thread.currentThread().getId()); } } private static class CallThread implements Callable<String> { public String call() throws Exception { System.out.println("CallThread running "); System.out.println("id: " + Thread.currentThread().getId()); return "callresult"; } } public static void main(String[] args) throws InterruptedException, ExecutionException { ExtendThread eh = new ExtendThread(); Thread th0 = new Thread(eh); RunThread rt = new RunThread(); Thread th1 = new Thread(rt); CallThread ct = new CallThread(); FutureTask<String> ft = new FutureTask<String>(ct); Thread th2 = new Thread(ft); th0.start(); th1.start(); th2.start(); System.out.println(ft.get()); } }
RunThread running id: 13 CallThread running id: 14 ExtendThread running callresult id: 12 +++++++++++++++ ExtendThread running CallThread running id: 12 RunThread running id: 13 id: 14 callresult
多次运行代码中main方法,发现每次打印结果都不一样,印证了相邻的两条语句甚至同一个语句中两个不同的运算符之间,都有可能插入其他线程或进程的动作。
一般使用实现runnable接口(多实现)和callable接口(有返回值)的方法来创建线程
3.线程中断
stop(),resume(),suspend()已不建议使用,stop()会导致线程不会正确释放资源,suspend()容易导致死锁。
java线程是协作式,而非抢占式
调用一个线程的interrupt() 方法中断一个线程,并不是强行关闭这个线程,只是跟这个线程打个招呼,将线程的中断标志位置为true,线程是否中断,由线程本身决定。
isInterrupted() 判定当前线程是否处于中断状态。
static方法interrupted() 判定当前线程是否处于中断状态,同时中断标志位改为false。
那么如何理解线程是否中断由线程本身决定?
package com.ljj.study; public class EndThread { private static class MyEndThread implements Runnable { public void run() { while (true) { System.out.println(Thread.currentThread().getName() + " running "); } } } private static class MyEndThread1 implements Runnable { public void run() { while (!Thread.currentThread().isInterrupted()) { System.out.println(Thread.currentThread().getName() + " running "); } System.out.println(Thread.currentThread().isInterrupted()); } } public static void main(String[] args) throws InterruptedException { // MyEndThread met = new MyEndThread(); // Thread t0 = new Thread(met); // t0.start(); // // System.out.println("begin "); // t0.interrupt(); MyEndThread1 met1 = new MyEndThread1(); Thread t1 = new Thread(met1); t1.start(); t1.sleep(30); System.out.println("begin "); t1.interrupt(); } }
t0线程虽然执行了interrupt方法,但是还是一直在打印,t1线程interrupt方法后就停止打印了,通过对比印证了上述所说。