Java并发系列:正确创建和停止线程的方式及Volatile失效场景

本文主要讲解:

本文源码地址:A01_实现线程的方式A02_正确停止线程
欢迎star我的:Github

正文开始

八种创建线程的方式


其实这八种创建线程的方式本质上可以归结为一种方式:那就是new Thread();因为源码最终都是调用该方法创建线程的。

  • implements Runnable:
public class RunnableDemo implements Runnable{
    @Override
    public void run() {
        System.out.println("i am RunnableDemo");
    }

    @Test
    public void test(){
        RunnableDemo r = new RunnableDemo();
        Thread t = new Thread(r);
        t.start();
    }

    @Test
    public void test2(){
        new Thread(()->{
            System.out.println("i am 匿名内部类");
        }).start();
    }
}
  • extends Thread:
public class ThreadDemo extends Thread{
    @Override
    public void run() {
        System.out.println("i am ThreadDemo");
    }

    @Test
    public void test() {
        ThreadDemo t = new ThreadDemo();
        t.start();
    }
}
  • 使用线程池:
public class ThreadPoolDemo {

    ExecutorService pools = Executors.newFixedThreadPool(10);
    @Test
    public void test() {
        pools.submit(() -> {
            System.out.println("ThreadPoolDemo");
        });
    }
}
  • 使用线程工厂:
在这里插入代码片
  • implements Callable:
public class CallableDemo implements Callable {
    @Override
    public Object call() throws Exception {
        System.out.println("i am CallableDemo");
        Thread.sleep(2000);
        return "i am CallableDemo return";
    }

    @Test
    public void test() throws InterruptedException {
        ExecutorService exec = Executors.newFixedThreadPool(10);
        // Future future = exec.submit(this::call);
        Future future = exec.submit(new CallableDemo());
        Thread.sleep(2000);
        System.out.println("\n=======test=========");
        try {
            System.out.println(future.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • implements FutureTask:
在这里插入代码片
  • 使用注解@Async:
在这里插入代码片
  • 定时器Timer创建线程:
在这里插入代码片

正确停止线程的方式

  • 使用interrupt
public class StopThread {
    @Test
    public void test() throws Exception {
        Thread t = new Thread(() -> {
            int count = 0;
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("======" + (count++) + "=====");
            }
        });
        t.start();
        Thread.sleep(5);
        t.interrupt();
    }

    //在sleep的情况下,能否感受到中断
    @Test
    public void test1() throws Exception {
        Thread t = new Thread(() -> {
            int count = 0;
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("======" + (count++) + "=====");
                try {
                    Thread.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //如果后续方法需要捕捉到中断,需要在此处加上 interrupt
                    Thread.currentThread().interrupt();
                }
            }
        });
        t.start();
        Thread.sleep(50);
        t.interrupt();
    }
}
  • 使用volatile
public class VolatileStopThread extends Thread {

    volatile boolean flag = false;
    @Override
    public void run() {
        int num = 0;
        while (!flag && num <= 1500) {
            if (num / 15 == 0) {
                System.out.println(++num);
            }
        }
    }

    @Test
    public void test() throws Exception{
        VolatileStopThread vs = new VolatileStopThread();
        Thread t = new Thread(vs);
        t.start();
        Thread.sleep(5000);
        vs.flag=true;
    }
}

Volatile停止线程失效的场景

  • 因为阻塞导致的失效
  • 失效原因:失效原因是 BlockingQueue 的put 操作会引起 阻塞
public void testnoAction() throws InterruptedException {
    ArrayBlockingQueue queue = new ArrayBlockingQueue(8);
    Produce p = new Produce(queue);
    Thread t = new Thread(p);
    t.start();

    Consumer c = new Consumer(queue);
    while (c.needmoreNums()) {
        System.out.println(c.queue.take() + "被消费了");
        Thread.sleep(100);
    }
    System.out.println("消费者结束了");
    p.flag = true;
    System.out.println("p.flag:" + p.flag);
}
  • 生产者
class Produce implements Runnable {
    public volatile boolean flag = false;
    BlockingQueue queue;
    public Produce(BlockingQueue q) {
        this.queue = q;
    }

    @Override
    public void run() {
        int num = 0;
        try {
            while (num <= 1000 && !flag) {
                if (num % 50 == 0) {
                    //此处因为一直在put,而队列的容量只有8个,所以装不下的时候,发送了阻塞
                    queue.put(num);
                    System.out.println("queue.put(num):" + num);
                }
                num++;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Produce end");
        }
    }
}
  • 消费者
class Consumer {
    BlockingQueue queue;

    public Consumer(BlockingQueue q) {
        this.queue = q;
    }

    public boolean needmoreNums() {
        if (Math.random() > 0.97) {
            return false;
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值