第一种 继承Thread类

自定义类,继承Thread类,并重写run()方法.

class MyThread1 extends Thread {
@Override
public void run() {
System.out.println("第一种方式Thread " + Thread.currentThread().getName());
}
}
public class Test {
public static void main(String[] args) throws Exception {
//第一种方式
MyThread1 thread1 = new MyThread1();
thread1.start(); MyThread1 thread1 = new MyThread1();
thread1.start(); MyThread1 thread2 = new MyThread1();
thread2.setName("zz");
thread2.start();
// 运行结果
// 第一种方式Thread Thread-0
// 第一种方式Thread Thread-1
// 第一种方式Thread zz
// 若不指定Name属性,能默认计数器0,1,2,3,4,5
}
}

  

第二种 实现Runnable接口

自定义类,实现Runnable接口的run方法. since JDK1.0

class MyThread2 implements Runnable {
@Override
public void run() {
System.out.println("第二种方式Runnable " + Thread.currentThread().getName());
}
}
public class Test {
public static void main(String[] args) throws Exception {
//第二种方式
Thread thread2 = new Thread(new MyThread2());
thread2.start();
// Lambda表达式方式->因为Runnable被注解FunctionalInterface标识表明该接口是一个函数式接口
new Thread(() -> {
System.out.println("第二种方式Runnable_Lambda " + Thread.currentThread().getName());
}).start();
// 运行结果
// 第二种方式Runnable Thread-0
// 第二种方式Runnable_Lambda Thread-1
}
}

  

第三种 实现Callable接口

已知Runnable的run方法无返回值,所以引入了有返回值的Callable接口

since JDK1.5

FutureTask中构造方法如下.

public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}

  

FutureTask类结构图如下.

 
 

因为FutureTask类实现了Runnable接口,所以线程实现方法如下.

public class Test {
public static void main(String[] args) throws Exception {
//第三种方式
FutureTask<String> thread3 = new FutureTask<>(new MyThread3());
new Thread(thread3).start();
System.out.println(thread3.get()); //获得回调值 FutureTask<String> thread4 = new FutureTask(()->{
System.out.println("Call");
return "Lambda回调";
});
new Thread(thread4).start();
System.out.println(thread4.get());
// 运行结果
// 第三种方式Callable Thread-0
// 回调
// Call
// Lambda回调
}
}
class MyThread3 implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("第三种方式Callable " + Thread.currentThread().getName());
return "回调";
}
}

  

第四种 线程池

交付线程池两种方式 submit或者execute方法,前者可接受Callable接口对象,有返回值,后者无返回值

public class Test {
public static void main(String[] args) throws Exception {
//第一种方式
MyThread1 thread1 = new MyThread1();
thread1.start();
//第二种方式
Thread thread2 = new Thread(new MyThread2());
thread2.start();
//第三种方式
FutureTask<String> thread3 = new FutureTask<>(new MyThread3());
new Thread(thread3).start();
System.out.println(thread3.get());
//第四种方式
ExecutorService pool = Executors.newFixedThreadPool(5);
Future<?> submit1 = pool.submit(new MyThread1());
Future<?> submit2 = pool.submit(new MyThread2());
Future<?> submit3 = pool.submit(new MyThread3());
System.out.println(submit1.get() + " " + submit2.get() + " " + submit3.get());
pool.shutdown();
// 运行结果
// 第一种方式Thread Thread-0
// 第二种方式Runnable Thread-1
// 第三种方式Callable Thread-2
// 回调
// 第一种方式Thread pool-1-thread-1
// 第二种方式Runnable pool-1-thread-2
// 第三种方式Callable pool-1-thread-3
// null null 回调
} }

  

特点

无论何种方式,都要使用Thread类中start方法开始多线程.

Runnable接口和Callable接口区别,后者可返回参数,参数类型Object.

线程池避免了线程频繁使用的创建和释放操作.

看完有什么不懂的欢迎在下面留言评论!

面试官:小伙子,说一说Java多线程有哪些创建方式吧的更多相关文章

  1. Java多线程——线程的创建方式

    Java多线程——线程的创建方式 摘要:本文主要学习了线程的创建方式,线程的常用属性和方法,以及线程的几个基本状态. 部分内容来自以下博客: https://www.cnblogs.com/dolph ...

  2. 阿里面试官:你连个java多线程都说不清楚,我招你进来干什么

    创建线程的方法 继承Thread类 继承Thread类,重写run方法,通过线程类实例.start()方法开启线程. public class TestThread1 extends Thread{ ...

  3. java 多线程5(创建方式)

    实现Runnable接口: 问题1:Runnable实现类的对象是线程对象吗? 答:不是,该对象只不过是实现了Runnable接口的对象而已,只有是Thread或Thread的子类才是线程对象. 问题 ...

  4. Java:多线程概述与创建方式

    目录 Java:多线程概述与创建方式 进程和线程 并发与并行 多线程的优势 线程的创建和启动 继承Thread类 start()和run() 实现Runnable接口 实现Callable接口 创建方 ...

  5. 大厂面试官最常问的@Configuration+@Bean(JDKConfig编程方式)

    大厂面试官最常问的@Configuration+@Bean(JDKConfig编程方式)   现在大部分的Spring项目都采用了基于注解的配置,采用了@Configuration 替换标签的做法.一 ...

  6. 使用goroutine+channel和java多线程+queue队列的方式开发各有什么优缺点?

    我感觉很多项目使用java或者c的多线程库+线程安全的queue数据结构基本上可以实现goroutine+channel开发能达到的需求,所以请问一下为什么说golang更适合并发服务端的开发呢?使用 ...

  7. 引用面试官文章 :如何准备Java初级和高级的技术面试

    本人最近几年一直在做java后端方面的技术面试官,而在最近两周,又密集了面试了一些java初级和高级开发的候选人,在面试过程中,我自认为比较慎重,遇到问题回答不好的候选人,我总会再三从不同方面提问,只 ...

  8. 一张图,让你和面试官聊一个小时的“Java内存模型”

    如果面试官问你:你了解 Java 内存模型吗? 你就可以使用这张图,按照这张图中的顺序和面试官开聊,正常情况下,聊一个小时是差不多的,这个时候,对你的处境是非常有益的,因为面试官的时间不多了.

  9. 面试官:兄弟,说说Java到底是值传递还是引用传递

    二哥,好久没更新面试官系列的文章了啊,真的是把我等着急了,所以特意过来催催.我最近一段时间在找工作,能从二哥的文章中学到一点就多一点信心啊! 说句实在话,离读者 trust you 发给我这段信息已经 ...

随机推荐

  1. poj1639,uva1537,uvalive2099,scu1622,fzu1761 Picnic Planning (最小限制生成树)

    Picnic Planning Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 10742   Accepted: 3885 ...

  2. 创建Sqlite数据库(一)

    对这方面的掌握不牢,慢慢深入吧,先执行一个sqlite语句,只会简单的.输出"创建"证明创建成功 public class MainActivity extends AppComp ...

  3. uart与usart区别

    uart 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种异步收发传输器,是电脑硬件的一部分.它将要传输的资料在串 ...

  4. vue学习笔记(六) ----- vue组件

    一.模块化与组件化 模块化的定义 模块化在Node中是一个规范,定义一些模块的相关的规则,从代码角度上来说,方便做区别,如果不使用模块化,写在js文件中不利于后期维护和扩展,从代码的层面上就把相关的功 ...

  5. Java学习的第四十七天

    1.用类函数来写时间类 import java.util.Scanner; public class Cjava { public static void main(String[]args) { T ...

  6. python框架Django使用xadmin管理后台数据

    Django使用xadmin管理后台数据 关注公众号"轻松学编程"了解更多. 作用:xadmin比Django内置的admin更美观.更方便. 一.导入xadmin(第三方库) 方 ...

  7. LWJGL3的内存管理,第一篇,基础知识

    LWJGL3的内存管理,第一篇,基础知识 为了讨论LWJGL在内存分配方面的设计,我将会分为数篇随笔分开介绍,本篇将主要介绍一些大方向的问题和一些必备的知识. 何为"绑定(binding)& ...

  8. Java入门(4)

    阅读书目:Java入门经典(第7版) 作者:罗格斯·卡登海德 面向对象编程(OOP)将程序视为对象的集合,确定程序要完成的任务,然后将这些任务指派给最适合完成它们的对象.换言之,计算机程序是一组对象, ...

  9. Flink的sink实战之一:初探

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. Boost.Accumulators累加器的简单使用

    Boost.Accumulators是一个累加器,实现的功能很简单,就是对一组数据进行操作,然后可以得到一些特征数据. 由于累加器默认不对数据进行储存操作,所以不能把它作为一个简单的容器使用. 简单使 ...