博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java实现多线程的两种方式
阅读量:2350 次
发布时间:2019-05-10

本文共 2523 字,大约阅读时间需要 8 分钟。

方式一:实现Runnable接口并重写其run()方法

线程可以驱动任务,因此你需要一种描述任务的方式,这可以由Runnable接口来提供。要想定义任务,只需要实现Runnable接口并先写run()方法,使得该任务可以执行你的命令。例如,下面的LiftOff任务将显示发射之前的倒计时:

package chapter21;/** * 通过实现Runnable的方式实现多线程 */public class LiftOff implements Runnable {	protected int countDown = 10;	//注意该变量是静态变量,在内存中只存在一个	private static int taskCount = 0;	//该变量是实例变量,每创建一个变量,值都会增加1	private final int id = taskCount ++;		public LiftOff() {			}		public LiftOff(int countDown) {		this.countDown = countDown;	}		public String status() {		return "#" + id + "(" + 				(countDown > 0 ? countDown : "LiftOff!") + "), ";	}	public void run() {		while(countDown-- > 0) {			System.out.print(status());			//将CPU从一个线程转移给另一个线程,不过不是绝对的,			//由CPU自己决定			Thread.yield();//		}	}}
标识符id可以用来区分任务的多个实例,它是final的,因为一旦被初始化之后就不希望被修改。

任务的run()方法通常会有某种形式的循环,使得任务一直运行下去直到不再需要,所以要设定跳出循环的条件(有一种选择是直接从run()返回)。通常run()被写成无限循环的形式,这就意味着,除非有某个条件使得run()终止,否则它将永远运行下去。

在run()中的静态方法Thread.yield()的调用是对线程调度器(Java线程机制的一部分,可以将CPU从一个线程转移给另一个线程)的一种建议,它在声明:当前线程中最重要的部分已经执行完毕了,此刻可以将CUP切换给其他的线程执行任务了。不过这完全是选择性的,这里使用它是因为它会在这些示例中产生更加有趣的输出:你更有可能看到任务换进换出的证据。

在下面的例子中,这个任务的run()不是由单独的线程驱动的,它是在main()直接调用的,实际上,这里使用main()线程驱动其他线程:

package chapter21;/** * 由main主线程来启动一个线程 */public class MainThread{	public static void main(String[] args) {		LiftOff launch = new LiftOff();		launch.run();	}}
运行结果:

#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(LiftOff!), 

二、使用Thread:继承Thread类,或传入Runnable的对象

将Runnable对象转变为工作任务的传统方式是把他提交给一个Thread构造器,下面的实例展示了如何使用Thread来驱动LiftOff对象:

package chapter21;/** * 使用Thread:继承Thread类,或传入Runnable的对象 */public class BasicThreads {	public static void main(String[] args) {		Thread t = new Thread(new LiftOff());		t.start();//使用主线程驱动一个线程		//主线程运行的任务		System.out.println("waiting for ListOff");	}}
运行结果:

waiting for ListOff

#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(LiftOff!),
下面的例子使用main()线程同时启动5个线程:

package chapter21;/** * 使用主线程启动 */public class MoreBasicThreads {	public static void main(String[] args) {		for(int i = 0; i < 5; i ++) {			new Thread(new LiftOff()).start();		}		//主线程中打印的内容		System.out.println("Waiting for LiftOff!");	}}
运行结果:

#1(9), #1(8), #1(7), #1(6), #1(5), #1(4), #1(3), #1(2), #1(1), #1(LiftOff!), Waiting for LiftOff!

#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #2(9), #0(LiftOff!), #2(8), #4(9), #3(9), #2(7), #4(8), #2(6), #3(8), #4(7), #3(7), #2(5), #3(6), #2(4), #4(6), #2(3), #2(2), #3(5), #2(1), #2(LiftOff!), #4(5), #3(4), #3(3), #3(2), #3(1), #3(LiftOff!), #4(4), #4(3), #4(2), #4(1), #4(LiftOff!), 

转载地址:http://yklvb.baihongyu.com/

你可能感兴趣的文章
STM32 HAL库、标准外设库、LL库(STM32 Embedded Software)
查看>>
51和AVR单片机
查看>>
DSP开发板
查看>>
stm32标准外设库和芯片资料下载地址
查看>>
ARM Keil MDK开发STM32工程模板
查看>>
NoSQL分类及常用软件
查看>>
ubuntu 16.04安装nVidia显卡驱动和cuda/cudnn踩坑过程
查看>>
基于STM32CubeMX创建STM32L496ZGTx的工程
查看>>
如何通过OpenFace实现人脸识别框架
查看>>
Angle和XBGoost以及Spark的性能对比
查看>>
IOS CoreImage实现人脸识别
查看>>
Tensorflow的高级封装
查看>>
Storm 1.1.0 集群安装
查看>>
图像压缩算法
查看>>
一张图看懂小程序全生态
查看>>
electron开发
查看>>
Electron如何调用NodeJS扩展模块
查看>>
NodeJS通过ffi调用DLL
查看>>
Electron通过ffi调用DLL
查看>>
Node.js & Electron的扩展模块
查看>>