Java并发编程-线程究竟有多少种实现方式?

我们熟悉的继承extends和实现runnable接口实现线程,但是这就算两种吗?首先,先写出来这最基础的两种。

Runnable接口实现线程方法
public class ThreadBaseDemo1 implements Runnable {
    public static void main(String[] args) {
        new Thread(new ThreadBaseDemo1()).start();
    }

    @Override
    public void run() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "运行");
    }
}

Thread类继承线程方法
public class ThreadBaseDemo1 extends Thread {
    public static void main(String[] args) {
        new Thread(new ThreadBaseDemo1()).start();
    }

    @Override
    public void run() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName());
    }
}
继续拓宽

其实还是有很多不同的形式实现线程的方法,下面看一下callable实现线程的方法

Callable接口实现线程方法
public class ThreadBaseDemo1 implements Callable<Integer> {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(16);
        Future<Integer> future = executorService.submit(new ThreadBaseDemo1());
        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            sum += i;
        }
        return sum;
    }
}

在这有的人会问,前两者和callable有什么区别呢?
callable的实现可以拥有返回值,并且支持抛出异常,这样就可以实现异步的思想,而runnable的返回值为void且不能抛出异常
future就是用来接收线程池处理的结果的。

但是扯了这么多,线程到底有多少种方式?

一种

请看下Thread的实现,里面主要的就是start方法,start底下的run方法就是执行传入target,中的run,所以不管是继承thread,或者是实现Runnable接口,还是用线程池submit,再或者是用future接收它,都是执行这个target.run()。所以只有一种方法

    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
哪种实现更好?

Java只能继承一个类,但是可以实现N个接口,从耦合度或者是组合聚合的角度上来看,当然是实现Runnable接口更好,毕竟物依稀为贵嘛。

如何正确的中断线程?
public class ThreadBaseDemo1 implements Runnable {
    public static void main(String[] args) {
        Thread thread = new Thread(new ThreadBaseDemo1());
        thread.start();
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();
    }

    @Override
    public void run() {
        int sum = 0;
        for (int i = 0; i < 100 && !Thread.currentThread().isInterrupted(); i++) {
            sum += i;
        }

        System.out.println(sum);
    }
}

每次执行累加业务之前,我们都先看看这个线程是否已经被终止,也就是说isInterrupted。

睡眠的时候会感知到中断吗?

public class ThreadBaseDemo1 implements Runnable {
    public static void main(String[] args) {
        Thread thread = new Thread(new ThreadBaseDemo1());
        thread.start();
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();
    }

    @Override
    public void run() {
        int sum = 0;
        for (int i = 0; i < 100 && !Thread.currentThread().isInterrupted(); i++) {
            sum += i;
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println(sum);
    }
}

在这里插入图片描述

在睡眠时期,可以被感知中断的,但是不能终止线程继续工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值