创建线程的三种方式(继承Thread,实现Runnable,实现callable)

继承Thread(不推荐使用,具有单继承局限性)

public class StartThread extends Thread{

    //线程入口点

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(i+"杨玉环真好玩!");
        }
    }

    public static void main(String[] args) {

        //创建线程对象
        StartThread startThread = new StartThread();
        startThread.start(); //调用start方法启动一条新线程


        //mani线程,主线程
        for (int i = 0; i < 10000; i++) {
            System.out.println("鲁班好可爱");
        }

        //startThread.run();//这里使用run方法不会开辟新线程,执行完run方法后会又回到主线程

        /*
        鲁班好可爱
        5杨玉环真好玩!
        6杨玉环真好玩!
        7杨玉环真好玩!
        8杨玉环真好玩!
        9杨玉环真好玩!
        鲁班好可爱

        可以知道,主线程和创建的线程是交替执行的

        */


    }
}

实现Runnable(推荐使用,它可以对同一资源开启多个线程)

package com.Luoking.Thread;

public class Runnable01 implements Runnable{
    private int ticket = 100;

    @Override
    public void run() {
        while(true){
            if(ticket<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticket+"张票");
            ticket--;
        }
    }


    public static void main(String[] args) {
        Runnable01 runnable01 = new Runnable01();
        new Thread(runnable01,"小敏").start();
        new Thread(runnable01,"小杰").start();
        new Thread(runnable01,"小平").start();
    }
}

但是实现Runable会出现并发问题,多个线程操作同一个资源,会出现线程不安全,数据紊乱

小敏拿到了第100张票
小敏拿到了第99张票
小敏拿到了第98张票
小杰拿到了第100张票

//这里第100张票出现了两次,在现实生活中,不可能存在

实现callable

package com.Luoking.Thread;

import java.util.concurrent.*;

public class testCallable implements Callable<Boolean> {
    //重写call方法,线程执行体就在call中
    @Override
    public Boolean call() throws Exception {//重写的call方法需要抛出异常
        for (int i = 0; i < 10; i++) {
            System.out.println("执行到"+i+"步");
        }
        return true;  //与其他开启线程不同的地方,这个开启线程会有返回值
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        testCallable T1 = new testCallable();
        testCallable T2 = new testCallable();
        testCallable T3 = new testCallable();
        //开启线程池
        ExecutorService pool = Executors.newFixedThreadPool(3);
        //线程池执行
        Future<Boolean> s1 = pool.submit(T1);
        Future<Boolean> s2 = pool.submit(T2);
        Future<Boolean> s3 = pool.submit(T3);

        //获取结果,  需要抛出异常
        Boolean b1 = s1.get();
        Boolean b2 = s1.get();
        Boolean b3 = s1.get();

        //关闭线程池
        pool.shutdownNow();

    }

}
posted @ 2022-04-27 16:17  小罗要有出息  阅读(57)  评论(0编辑  收藏  举报