Java——多线程高并发系列之创建多线程的四种方式(Thread、Runnable、Callable、线程池)

简介: Java——多线程高并发系列之创建多线程的四种方式(Thread、Runnable、Callable、线程池)

文章目录:


写在前面

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

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

传统写

匿名内部类写法

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

Demo4(线程池 + Callable接口)

写在前面


历时一个星期,终于整完了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("t1").start();
//        new MyThread("t2").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()方法)


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);
    }
}


Demo4(线程池 + Callable接口)


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();
    }
}

相关文章
|
7天前
|
安全 Java 开发者
深入解读JAVA多线程:wait()、notify()、notifyAll()的奥秘
在Java多线程编程中,`wait()`、`notify()`和`notifyAll()`方法是实现线程间通信和同步的关键机制。这些方法定义在`java.lang.Object`类中,每个Java对象都可以作为线程间通信的媒介。本文将详细解析这三个方法的使用方法和最佳实践,帮助开发者更高效地进行多线程编程。 示例代码展示了如何在同步方法中使用这些方法,确保线程安全和高效的通信。
27 9
|
7天前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
4月前
|
Java 开发者
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
Java面试题:请解释内存泄漏的原因,并说明如何使用Thread类和ExecutorService实现多线程编程,请解释CountDownLatch和CyclicBarrier在并发编程中的用途和区别
56 0
|
25天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
28 1
|
Java
Java基础系列-第一章 创建Thread的6种方式和线程常用方法
读完本章节,您将掌握如何创建线程和线程的常用方法。
157 1
Java基础系列-第一章 创建Thread的6种方式和线程常用方法
|
缓存 安全 Java
JAVA Thread Dump分析线程竞争
JAVA Thread Dump分析线程竞争
87 0
|
Java 调度
【Java|多线程与高并发】 使用Thread 类创建线程的5种方法&&如何查看程序中的线程
多线程编程主要是为了更好地解决并发编程这个问题,因为创建销毁调度一个进程开销比较大(消耗资源多和速度慢),进程之所以开销比较大,主要是在"资源的分配和回收上"而线程也被称为"轻量级进程",因此在解决并发编程这个问题上,线程的创建销毁调度的更快一些.
|
Java 调度
Java多线程(2)--Thread类继承和Runnable接口创建线程
Java多线程(2)--Thread类继承和Runnable接口创建线程
119 0
Java多线程(2)--Thread类继承和Runnable接口创建线程
|
安全 Java Linux
【Java原理探索】站在Linux操作系统角度去看Thread(线程) | Java开发实战
【Java原理探索】站在Linux操作系统角度去看Thread(线程) | Java开发实战
186 0
|
Java 程序员 API
java多线程编程_Thread类_线程状态的理解
java多线程编程_Thread类_线程状态的理解
74 0
java多线程编程_Thread类_线程状态的理解