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方法后就停止打印了,通过对比印证了上述所说。

 

 

 

 

posted @ 2018-11-24 21:07  sagan15  阅读(293)  评论(0编辑  收藏  举报