Java——多线程高并发系列之创建多线程的三种方式(ThreadRunnableCallable)

Posted 张起灵-小哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java——多线程高并发系列之创建多线程的三种方式(ThreadRunnableCallable)相关的知识,希望对你有一定的参考价值。

文章目录:

写在前面

Demo1(继承Thread类,重写run()方法)

Demo2(实现Runnable接口,重写run()方法)

Demo3(实现Callable接口,重写call()方法)


写在前面

历时一个星期,终于整完了Java多线程高并发这个系列的相关内容,这是最后一篇关于多线程的文章了,打算回到最初学习多线程的起点:总结一下创建多线程的三种方式吧。


Demo1(继承Thread类,重写run()方法)

package com.szh.begin;

/**
 * 实现多线程的第一种方式:继承Thread类,重写run()方法
 */
public class Test01 {

    static class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " ---> " + i);
            }
        }
    }

    public static void main(String[] args) {
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();

        t1.setName("t1");
        t2.setName("t2");

        //start方法的作用是:启动一个分支线程,在JVW中开辟一个新的栈空间
        //只要栈空间开辟出来,start方法就结束了,线程就启动成功了,启动成功的线程会自动调用run方法
        //run方法在分支线程的栈底部,main方法在主线程的栈底部,run和main是平级的
        t1.start();
        t2.start();

        //上面的代码也可以写成下面这种形式
//        new MyThread().start();
//        new MyThread().start();
    }
}


Demo2(实现Runnable接口,重写run()方法)

传统写法

package com.szh.begin;

/**
 * 实现多线程的第二种方式:实现Runnable接口,重写run()方法
 * 传统写法
 */
public class Test02 {

    static class MyRunnable implements Runnable {

        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " ---> " + i);
            }
        }
    }

    public static void main(String[] args) {
        new Thread(new MyRunnable(),"t1").start();
        new Thread(new MyRunnable(),"t2").start();
    }
}

匿名内部类写法

package com.szh.begin;

/**
 * 实现多线程的第二种方式:实现Runnable接口,重写run()方法
 * 匿名内部类写法
 */
public class Test03 {

    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " ---> " + i);
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " ---> " + i);
                }
            }
        }).start();

    }
}


Demo3(实现Callable接口,重写call()方法)

使用Future接收线程的执行结果

package com.szh.begin;

import java.util.concurrent.*;

/**
 * 实现多线程的第三种方式:实现Callable接口,重写call()方法
 * 使用Future接收线程的执行结果
 */
public class Test04 {

    static class MyCallable implements Callable<Object> {

        @Override
        public Object call() throws Exception {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " ---> " + i);
            }
            return "当前执行线程的id为:" + Thread.currentThread().getId();
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建一个固定大小的线程池
        ExecutorService service= Executors.newFixedThreadPool(2);
        //提交执行
        Future<Object> future1=service.submit(new MyCallable());
        Future<Object> future2=service.submit(new MyCallable());
        //获取call()方法的返回值(即线程执行结果的返回值)
        Object obj1=future1.get();
        Object obj2=future2.get();
        //打印
        System.out.println(obj1);
        System.out.println(obj2);
        //关闭线程池
        service.shutdown();
    }
}

使用FutureTask接收线程的执行结果

package com.szh.begin;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 实现多线程的第三种方式:实现Callable接口,重写call()方法
 * 使用FutureTask接收线程的执行结果
 */
public class Test05 {

    static class MyCallable implements Callable<Object> {

        @Override
        public Object call() throws Exception {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " ---> " + i);
            }
            return "当前执行线程的id为:" + Thread.currentThread().getId();
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //new一个未来任务类对象,参数传入一个Callable接口实现类对象
        FutureTask<Object> task1=new FutureTask<>(new MyCallable());
        FutureTask<Object> task2=new FutureTask<>(new MyCallable());
        //创建两个线程对象,参数传入一个FutureTask对象,之后启动线程
        new Thread(task1).start();
        new Thread(task2).start();
        //获取t1线程的执行结果
        Object obj1=task1.get();
        Object obj2=task2.get();
        System.out.println(obj1);
        System.out.println(obj2);
    }
}

 

以上是关于Java——多线程高并发系列之创建多线程的三种方式(ThreadRunnableCallable)的主要内容,如果未能解决你的问题,请参考以下文章

JAVA-多线程-创建线程的三种方式

[Java多线程]线程创建的三种方式,线程的互斥,线程的同步

[Java多线程]线程创建的三种方式,线程的互斥

[Java多线程]线程创建的三种方式,线程的互斥,线程的同步

Java——多线程高并发系列之JUC三大辅助类(CountDownLatchCyclicBarrierSemaphore)

Java——多线程高并发系列之JUC三大辅助类(CountDownLatchCyclicBarrierSemaphore)