创建线程的方式

创建线程的方式

通常情况下我们一般使用两种方式来创建线程,即继承Thread和实现runnable接口,这两种创建方式线程执行完是没有返回结果的。其实还有第三种方式,那就是实现callable接口,该中方式线程执行完具有返回结果,下面将会从代码角度来分别讲解三种实现方式。

继承Thread

public class Main {

    public static void main(String []args){

        MyThread thread = new MyThread();
        thread.start();
        System.out.println("main------"+Thread.currentThread().getName());


    }

    public static class MyThread extends Thread{
        @Override
        public void run() {
            try {
                System.out.println("before sleep..."+Thread.currentThread().getName());
                Thread.sleep(2000);
                System.out.println("after sleep..."+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}


// 输出
before sleep...Thread-0
main------main
after sleep...Thread-0

实现runnable接口

public class Main {

    public static void main(String []args){

        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
        Thread thread1 = new Thread(myRunnable);
        thread1.start();
        System.out.println("main------"+Thread.currentThread().getName());


    }


    public static class MyRunnable implements Runnable{

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

// 输出
main------main
before sleep...Thread-0
before sleep...Thread-1
after sleep...Thread-0
after sleep...Thread-1

实现callable接口

Callable并不像Runnable那样通过Thread的start方法就能启动实现类的run方法,它通常利用ExecutorService的submit方法去启动call方法自执行任务,而ExecutorService的submit又返回一个Future类型的结果,因此Callable通常也与Future一起使用。

public class CallableAndFutureTest {


    public static void main(String []args){
        //创建线程池  创建一个单线程化的线程池
        ExecutorService es = Executors.newSingleThreadExecutor();
        //创建Callable对象任务
        MyCallable calTask=new MyCallable();
        //提交任务并获取执行结果
        Future<Integer> future =es.submit(calTask);
        //关闭线程池
        es.shutdown();
        try {
            System.out.println("主线程在执行其他任务 ----"+Thread.currentThread().getName());
            // 获取异步执行的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。
            if(future.get()!=null){
                //输出获取到的结果
                System.out.println("future.get()-->"+future.get());
            }else{
                //输出获取到的结果
                System.out.println("future.get()未获取到结果");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("主线程在执行完成----"+Thread.currentThread().getName());

    }


    public static class MyCallable implements Callable<Integer> {

        private int sum;
        @Override
        public Integer call() throws Exception {
            System.out.println("Callable子线程开始计算啦! ----"+Thread.currentThread().getName());
            Thread.sleep(2000);

            for(int i=0 ;i<5000;i++){
                sum=sum+i;
            }
            System.out.println("Callable子线程计算结束!----"+Thread.currentThread().getName());
            return sum;
        }
    }

}

// 输出
Callable子线程开始计算啦! ----pool-1-thread-1
主线程在执行其他任务 ----main
Callable子线程计算结束!----pool-1-thread-1
future.get()-->12497500
主线程在执行完成----main

当然callable还能和FutureTask结合使用,具体如何使用如下:

public class CallableAndFutureTest {


    public static void main(String []args){

        testCallableAndFutureTask();
    }

    public static void testCallableAndFutureTask(){
        //创建线程池  创建一个单线程化的线程池
        ExecutorService es = Executors.newSingleThreadExecutor();
        //创建Callable对象任务
        MyCallable calTask=new MyCallable();
        //提交任务并获取执行结果
        FutureTask<Integer> futureTask = new FutureTask<Integer>(calTask);
        es.submit(futureTask);
        //关闭线程池
        es.shutdown();
        try {
            System.out.println("主线程在执行其他任务 ----"+Thread.currentThread().getName());

            // 获取异步执行的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。
            if(futureTask.get()!=null){
                //输出获取到的结果
                System.out.println("future.get()-->"+futureTask.get());
            }else{
                //输出获取到的结果
                System.out.println("future.get()未获取到结果");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("主线程在执行完成----"+Thread.currentThread().getName());
    }


    public static class MyCallable implements Callable<Integer> {

        private int sum;
        @Override
        public Integer call() throws Exception {
            System.out.println("Callable子线程开始计算啦! ----"+Thread.currentThread().getName());
            Thread.sleep(2000);

            for(int i=0 ;i<5000;i++){
                sum=sum+i;
            }
            System.out.println("Callable子线程计算结束!----"+Thread.currentThread().getName());
            return sum;
        }
    }

}

参考链接

https://blog.csdn.net/javazejian/article/details/50896505

猜你喜欢

转载自blog.csdn.net/u010349644/article/details/79996728