java线程三种创建方式与线程池的应用
前言:多线程下程序运行的结果是随机的,以下案例代码的运行结果仅供参考
一 通过继承Thread线程创建的方法与执行的步骤
/*
1 继承Thread 2重写run方法 3创建线程继承类的子类
4 调用start(一个线程只能通过调用一次start来进行启动)*/
class MyThread extends Thread{public MyThread(String name){//调用Thread类中的构造方法才能顺序初始化成功线程名super(name);}@Overridepublic void run() {for (int i = 0; i < 3; i++) {//线程名(默认):Thread-0,currentThread是获取当前的线程System.out.println(Thread.currentThread().getName() + i);}}
}public class ThreadTest {/*当前主线程是main线程,我们在此又开了个名为myThread的线程,main线程与thread线程的执行时顺序是随机的由于myThread的启动和被分配cpu时间片都需要时间,所以通常是main线程先执行只有start才能启动一个线程,启动后需要抢占cpu资源,抢占成功才能执行线程中的run方法,如果直接调用线程的run方法相当于在主线程main中正常的调用一个对象myThread的run方法若没有手动设置线程名称时,会自动分配一个线程的名称,如线程对象myThread会被自动分配线程名称Thread-0设置线程名称是为了区分当前正在执行的线程是哪一个线程,所以在设置线程名称时应避免重复!*/public static void main(String[] args) throws InterruptedException {MyThread myThread = new MyThread("myThread");//start方法是由新建态=> 就绪态。有两步①启动线程②调用线程的run方法myThread.start();System.out.println("========以下是main线程的执行步骤========");for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}
}
二 通过实现Runnble的方法
/*
①创建一个Runnable的实现类②实现类去重写接口的run方法③创建实现类的对象
④将该对象作为参数传入到Thread构造器来构造一个Thread类型的对象⑤通过该thread对象调用时start*/
class MyRun implements Runnable{@Overridepublic void run() {for (int i = 0; i < 3; i++) {//线程名(默认):Thread-0,currentThread是获取当前的线程System.out.println(Thread.currentThread().getName() + i);}}
}public class ThreadTest {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new MyRun());thread.setName("mythread");thread.start();System.out.println("========以下是main线程的执行步骤========");for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}
}
三、实现Callable的方式
方法三比方法二好,原因①call方法可以有返回值 ②Callable支持泛型③call可以声明抛出异常信息而run中不能
/*
相比较Runable接口,call()方法新增捕获和抛出异常和返回值的功能,实现步骤如下:
①创建一个Callable的实现类并重写call方法,将线程需要执行的任务写到call方法中
②实例化一个该实现类的对象callable
③将callable作为参数构造一个FutureTask的对象ftt
④将ftt作为参数(Runnable接口类型的引用target)构造Thread对象thread
⑤thread.start()启动线程
补充:call的返回值类型即为Callable的泛型类型,通过ftt.get()可以返回call方法的返回值*/
class MyCall implements Callable<Integer>{@Overridepublic Integer call() throws Exception {for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().getName() + ":" +i);}return 1;}
}public class ThreadTest {public static void main(String[] args) throws InterruptedException, ExecutionException {Callable<Integer> callable = new MyCall();FutureTask<Integer> ftt = new FutureTask<Integer>(callable);Thread thread = new Thread(ftt);thread.start();System.out.println(ftt.get());}
}
四、通过线程池的方式
由于线程的创建与销毁都是很耗费资源的工作,在高并发的情况下对性能影响非常大,解决:可以提前创建多个线程放入线程池,使用的时不是现造而是去线程池中取,使用完不是销毁而是重新放回线程池,避免频繁的创建于销毁,实现重复利用,类似于公交车,优势非常明显,降低响应时间(节约了创建线程的时间)节约系统资源(重复利用线程池的线程减少了创建和销毁线程的频率)提高系统系统,利于管理(例如可以通过参数指定线程池大小,池内最大线程数,线程保持时间)
class MyRun implements Runnable{@Overridepublic void run() {System.out.println("这是MyRun");}
}class MyCall implements Callable{@Overridepublic Object call() throws Exception {return 1;}
}
/*
1 创建一个指定线程数量的线程池对象service
2 将service强转为ThreadPoolExecutor以便设置线程池的属性
3 需要传入Runnable或Callable接口实现类的对象(匿名对象)作为参数执行指定的线程的操作
4 关闭连接池
*/public class ThreadTest {public static void main(String[] args) throws InterruptedException, ExecutionException {//1 创建一个指定线程数量的线程池对象serviceExecutorService service = Executors.newFixedThreadPool(10);//2 将service强转为ThreadPoolExecutor以便设置线程池的属性ThreadPoolExecutor executor = (ThreadPoolExecutor)service;//3 需要传入Runnable或Callable接口实现类的对象(匿名对象)作为参数执行指定的线程的操作service.execute(new MyRun());service.submit(new MyCall());//4 关闭连接池service.shutdown();}
}
推荐学习:线程的安全问题与三种解决方法
java线程三种创建方式与线程池的应用相关推荐
- 多线程—Thread类及线程三种创建方式及对比
线程创建的3种方法: 1.继承Thread类并重写run方法 Thread类方法: Thread Thread.currentThread() :获得当前线程的引用.获得当前线程后对其进行操作. Th ...
- Java数组—三种创建方式与区别
Java创建数组有三种方式 1. 第一种方式 int arr [ ] = new int [5] ; 属于动态创建,声明并创建内存空间,等待赋值. //创建数组的第一种方式 //属于动态创建,声明并 ...
- java线程的任务的三种创建方式,严格地说,就一种,就是如何重写Runnable接口的run()方法
仅简单演示Java中线程任务的三种创建方式 第一种:使用了适配器模式,有返回值,能抛出异常,任务代码写在Callable.call()方法中,Runnable的run方法会通过适配器调用到Callab ...
- 线程的三种创建方式以及代码实现
线程和进程的概念 一个进程可以有多个线程 程序:是指令和数据的有序集合(静态的) 进程:是执行程序的一次执行过程(动态的),是系统资源分配的单位.在操作系统中运行的程序就是进程. 通常在一个进程中可以 ...
- 线程的三种创建方式和他们的优缺点
文章目录 一.线程的三种创建方式 1.继承Thread 2.实现Runable接口 3.实现Callable接口 二.三种创建方式的优缺点 1.使用Runnable接口比使用继承Thread的优势 2 ...
- JavaScript 闭包的详细分享(三种创建方式)(附小实例)
JavaScript闭包的详细理解 一.原理:闭包函数--指有权访问私有函数里面的变量和对象还有方法等:通俗的讲就是突破私有函数的作用域,让函数外面能够使用函数里面的变量及方法. 1.第一种创建方式 ...
- Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)
阅读目录 一.MVC与MTV 二.多对多表的创建 三.ajax,前后端传输编码格式contentType 四.批量插入数据与自定义分页器 摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端 ...
- Django09:图书管理系统笔记/choices用法/ MTV与MVC模型/多对多三种创建方式
图书管理系统笔记 redirect括号内可以直接写url 也可以直接写别名 但如果别名需要参数,必须使用reverse解析. choices用法 使用场景:能列举完全的数据 #使用方法:xxx_cho ...
- Servlet 的三种创建方式
Servlet 创建有三种方式. 1.实现 Servlet 接口 因为是实现 Servlet 接口,所以我们需要实现接口里的方法. 下面我们也说明了 Servlet 的执行过程,也就是 Servlet ...
最新文章
- kubernetes关键特性和概述
- json的序列化与反序列化
- C 格式化的输入输出(printf scanf)
- 【MySQL】MySQL5.6新特性之Index Condition Pushdown
- matlab out of memory产生原因和解决办法
- C语言合并排序实例代码
- invalid currency could not be saved in AG3
- 计算机入门与学习回忆(一)
- LeetCode 1942. 最小未被占据椅子的编号(set)
- java 多线程同步_详解Java多线程编程中的线程同步方法
- 快速排序算法理解-python
- 强迫症告辞!三星Galaxy S11这“凌乱”的后置5摄,感受下
- python和c++哪个好-c语言和python哪个好入门?
- 云原生:云计算时代命题之终极解决方案
- Java开发笔记(一百四十七)通过JDBC管理数据库
- delphi2007 打开项目时,突然报错,提示microsoft.net borland 报错
- 计算机专业的八字,生辰八字五行计算器
- 线上幽灵:世界头号黑客米特尼克自传
- 论软件架构建模技术与应用
- 【Shell】Sed 删除、替换、增加字符串
热门文章
- c#中queue的用法
- Vue.set()详解
- [HTTP] Nginx代理以及面向未来的HTTP
- 夯实基础,彻底掌握js的核心技术(四):ES5、ES6对象方法详解
- css3实现背景渐变的方法
- PyTorch入门(二)--实现简单神经网络
- 【CV实战】Ubuntu18.04源码编译安装opencv-3.4.X+测试demo
- mysql获取当前时间的订单_mysql获取当前时间,及其相关操作
- 剑指offer-JZ82 二叉树中和为某一值的路径(一)(附区分DFS和回溯)
- ASP.NET Core 入门教程 8、ASP.NET Core + Entity Framework Core 数据访问入门