多线程的三种建立方式
来源:互联网 发布:informix sql 语法 编辑:程序博客网 时间:2024/06/06 05:18
继承Thread类创建线程类
public class Thread extends Object implements Runnable
- 定义Thread类的子类,并重写其run()方法
- 创建Thread子类的实例,即创建了线程对象
- 调用线程对象的start()方法启动线程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
Thread类已经继承了Object
Object类创建了name选项 并且有其getName(),setName()方法
在继承Thread的类里面使用时只需要用this引用上面两个副线程和主线程随机切换,又因为使用的是继承Thread的类所以两个副线程不能共享资源
start()方法调用后并不是立即执行多线程代码,而是使得该线程编程可运行状态,什么时候运行是由操作系统决定的
实现Runnable接口创建线程类
public Thread()
public Thread(Runnable target)
public Thread(Runnable target,String name)
- 定义Runnable接口的实现类,并重写该接口的run()方法
- 创建Runnable实现类的实例,并以此作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
上面的结果是两个副线程和主线程随机切换,但是并没有共享资源,因为他们根本没有能用来共享的资源。
start()方法调用后并不是立即执行多线程代码,而是使得该线程编程可运行状态,什么时候运行是由操作系统决定的
继承Thread类和创建Runnable接口的共享资源详解
在只有可以用来共享的资源时候,也就是同用一个实例化对象。两个创建方式在共享资源时才会有所区别,否则它们都不会共享资源共享资源通常用private static 修饰符来修饰。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
B运行 count= 5
A运行 count= 5
B运行 count= 4
B运行 count= 3
B运行 count= 2
B运行 count= 1
A运行 count= 4
A运行 count= 3
A运行 count= 2
A运行 count= 1
正是因为有了private int count=5;一句才有了共享资源,但这是继承Thread类的子类,并不能共享资源
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
C运行 count= 15
D运行 count= 14
E运行 count= 13
D运行 count= 12
D运行 count= 10
D运行 count= 9
D运行 count= 8
C运行 count= 11
E运行 count= 12
C运行 count= 7
E运行 count= 6
C运行 count= 5
E运行 count= 4
C运行 count= 3
E运行 count= 2
同样的正是因为有了private int count=15这个共同的实例化对象,实现Runnable的类才可以共享资源
那么为什么继承Thread类的子类实现Runable接口的类在共享资源时有区别呢?
因为Java中只能支持单继承,单继承特点意味着只能有一个子类去继承
而Runnabl接口后可以跟好多类,便可以进行多个线程共享一个资源的操作
使用Callable和Future创建线程
Callable怎么看起来都像Runnable接口的增强版,Callable有一个call()方法相当于Runnable的run()方法,但是功能却更加强大:
call()方法可以有返回值
call()方法可以声明抛出异常Callable接口有泛型限制,Callable接口里的泛型形参类型与call()方法的返回值类型相同。
而且Callable接口是函数式接口,因此可使用Lambda表达式创建Callable对象
Runnable接口也是函数式接口,因此也可以使用Lambda表达式创建Runnable对象
- 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,再创建Callable实现类的实例
- 使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法
- 使用FutureTask类对象作为Thread对象的target创建并启动新线程
- 调用FutureTask对象的get()方法来获得子线程结束后的返回值
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
使用Lambda表达式的Callable和Future创建的线程
- 多线程的三种建立方式
- 多线程的三种建立方式
- 多线程的三种建立方式
- 多线程的三种方式
- JAVA多线程实现的三种方式
- Java多线程实现的三种方式
- IOS多线程的三种方式
- 多线程-创建线程的三种方式
- JAVA多线程实现的三种方式
- JAVA多线程实现的三种方式
- JAVA多线程实现的三种方式
- JAVA多线程实现的三种方式
- IOS多线程三种方式的优缺点
- Java多线程的三种实现方式
- JAVA多线程实现的三种方式
- JAVA多线程实现的三种方式
- JAVA多线程实现的三种方式
- java多线程实现的三种方式
- c++-algorithm 头文件排序sort
- 常见数据结构与算法整理总结(下)
- CSS图片阴影+鼠标移上图片放大、变形
- python中利用re模块使用正则表达式
- VC6.0 C语言精华代码
- 多线程的三种建立方式
- FFmpeg 的sws_getContext函数 、sws_scale函数
- 『 Spark 』7. 使用 Spark DataFrame 进行大数据分析
- malloc hook初探
- [RK3288][Android6.0] 调试笔记 --- CPU默认调度策略
- 读书笔记--C陷阱与缺陷(七)
- 201403-1 相反数
- 面向对象设计原则之单一职责原则
- cmd 输入sqlplus 后 “请输入用户名”显示乱码