JUC之线程的启动和中止

一、线程的实现

  1、继承Thread类

public class ThreadDemo extends Thread {
    @Override
    public void run() {
        System.out.println("1111");
    }

    public static void main(String[] args) {
        Thread thread = new ThreadDemo();
        thread.start();
    }
}

  2、实现Runnable接口

public class RunnableDemo implements Runnable {
    @Override
    public void run() {
        System.out.println("线程名->" + Thread.currentThread().getName());
    }
    public static void main(String[] args) {
        Thread thread = new Thread(new RunnableDemo());
        thread.start();
    }
}

  3、实现Callable接口

/* ==============实现Callable<Object>接口================
 * 1.线程有返回值
 * 2.可通过Future接口的实现类保存call()方法的返回值
 * 3.Callable<String>中的String是call()方法的返回值类型
 * 4.FutureTask是Runnable的子类型
 */
public class CallableDemo implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "线程名->" + Thread.currentThread().getName();
    }
    public static void main(String[] args) {
        CallableDemo callableDemo = new CallableDemo();
        FutureTask<String> futureTask = new FutureTask<String>(callableDemo);
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println("主线程:" + Thread.currentThread().getName());
        try {
            String object = futureTask.get();
            System.out.println(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  4.总结:   

  A、第一种方法和第二种方式基本相同,但是推荐使用实现Runnable接口的方式,根据面向接口编程的思想,接口扩展性更强,而类只能被单继承,扩展性差, 如果需要需要集成其他类就无法实现。
  B、 如果使用场景中,线程需要返回执行结果或者需要返回执行结果,则使用用Callable的方式。

二、线程的中止

  1、stop()方法

    stop()方法是java.lang.Thread提供的停止线程的方法,目标前JDK已经标记为过时,不推荐使用,就不在写demo介绍。
    过时原因:
    (1) stop()可以停止一个正在运行的线程,同时,终止线程的run()方法中正在执行的任务,包括catch
      或finally语句中的,并抛出ThreadDeath异常,操作共享资源,就会导致共享资源不完整,造成数据不安全问题。
    (2) stop()方法在执行时会释放所持有的所有锁,也会对程序执行造成影响,造成数据不一致的影响。

  2、interrupt()方法

    interrupt()方法执行后并不会终止线程执行,而是改变isInterrupted()的状态,线程内部通过感知isInterrupted()的状态
    决定线程的终止时间,也就是说如果没有上文中的if判断,线程会一直执行下,并不会终止。

public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(() -> {
        while (true) {
            if(Thread.currentThread().isInterrupted()) {
                break;
            }
            System.out.println("测试");
        }
    }, "线程A");
    thread.start();
    System.out.println("线程中断状态:\t" + thread.isInterrupted());
    TimeUnit.MILLISECONDS.sleep(100);
    thread.interrupt();
    System.out.println("线程中断状态:\t" + thread.isInterrupted());
}

 

  3、 标志位中止线程

  使用标志位的方式和interrupt()方法相似,在线程外定义一个线程可见的标志,通过线程感知标志的状态来终止线程。

public class DmConnectionTest implements Runnable{
    //为保证变量可见性,用volatile修饰
    private volatile boolean flag = true;
    public static void main(String[] args) throws InterruptedException {
        DmConnectionTest dmConnectionTest = new DmConnectionTest();
        Thread thread = new Thread(dmConnectionTest);
        thread.start();
        System.out.println("线程中断状态:\t" + dmConnectionTest.flag);
        TimeUnit.MILLISECONDS.sleep(100);
        dmConnectionTest.flag = false;
        System.out.println("线程中断状态:\t" + dmConnectionTest.flag);
    }
    @Override
    public void run() {
        while (flag) {
            System.out.println("测试");
        }
        System.out.println("线程执行结束");
    }
}    

总结: A.stop()由于会造成数据安全性问题,现在已经不再使用
    B.使用标志位方法更简单,但是如果线程是阻塞的,则不能使用,所以推荐JDK自带的方法interrupt();

posted @ 2020-05-25 09:17  哲雪君!  阅读(247)  评论(0编辑  收藏  举报