Java 基本线程机制

本文介绍了进程的独立性、动态性和并发性,并详细阐述了Java中的线程机制。通过实现Runnable接口和继承Thread类两种方式创建线程,展示了线程如何并发执行任务,并通过示例展示了线程的并发执行效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当一个程序进入内存运行时,即变成一个进程。进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。

独立性:进程是系统中独立存在的实体,它可以拥有自己独立的资源,每一个进程都拥有自己私有的地址空间。在没有经过进程本身允许的情况下,一个用户进程不可以直接访问其他进程的地址空间。

动态性:进程与程序的区别在于,程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合。在进程中加入了时间的概念。进程具有自己的生命 周期和各种不同的状态,这些概念在程序中都是不具备的。

并发性:多个进程可以在单个处理器上并发执行,多个进程之间不会互相影响。

大部分操作系统都支持多进程并发运行,并发编程可以将程序划分为多个分离的,独立运行的任务。通过使用多线程机制,这些独立任务中的每一个都将由执行线程来驱动。一个线程就是在进程中的一个单一的顺序控制流,因此,单个进程可以拥有多个并发执行的任务,其底层机制是切分CPU时间。在使用线程时,CPU将轮流给每个任务分配占用时间,划分成片段分配给所有任务,当然,也有个例外情况,就是该程序确实运行在多个CPU之上。总而言之,操作系统可以同时执行多个任务,每个任务就是进程;进程可以同时执行多个任务,每个任务就是线程。

实现线程主要有两种方式:

  1. 实现Runnable接口

线程可以驱动任务,想要定义任务,只需要实现Runnable接口并编写run()方法,使该任务可以执行命令,如:

public class Demo implements Runnable {
	protected int count = 10;
	private static int taskCount = 0;
	private final int id = taskCount++;
	public Demo() {
	}
	public Demo(int count) {
		this.count = count;
	}	
	public String status(){
		return "倒计时" + id + "(" + (count > 0 ? count : "go") + "),";
	}
	@Override
	public void run() {
		while(count --> 0){
			System.out.println(status());
			Thread.yield();
		}		
	}
}

该例子将显示发射之前的倒计时,final修饰的id可以用来区分任务的多个实例,run()方法中对静态方法Thread.yield()的调用是Java线程机制的一部分,可以将CPU从一个线程转移给另外一个线程,通俗点说,就是已经执行完该程序生命周期中最重要的部分,可以将CPU的占用切换给其他任务执行一段时间。

例子:

public class RunDemo {
	public static void main(String[] args) {
		Demo demo = new Demo();
		demo.run();
	}
}

输出结果:

该例子中的run()不是由单独的线程驱动的,是在main()中直接调用,实际上,该例子仍然使用了线程,即总是分配给main()的那个线程。当从Runnable 导出的一个类时,它必须具有run()方法,该方法不会产生任何内在的线程能力,要实现线程行为,必须显式地将一个任务附在到线程上。

     2.继承Thread类

Runnable对象转化为工作任务的传统方式就是把它提交给一个Thread构造器,如:

public class ThreadDemo {
	public static void main(String[] args) {
		Demo demo = new Demo();
		Thread thread = new Thread(demo);
		thread.start();
System.out.println("---Thread---");
	}
}

输出结果:

Thread构造器只需要一个Runnable对象。调用Thread对象的start()方法为该线程执行必需的初始化操作,然后调用Runnable的run()方法,以便在这个新线程中启动该任务。尽管start()方法看起来是产生了一个对长期运行方法的调用,但从输出中可以看到,“---Thread---”消息在倒计时完成之前就出现了,实际上,产生的是对Demo.run()的方法的调用,并且这个方法还没有完成,但是因为Demo.run()是由不同的线程执行的,因此仍旧可以执行main()线程中的其他操作,这种并不局限于main()线程,任何线程都可以启动另一个线程。因此,程序会同时运行两个方法,main()和Demo.run()是程序中与其它线程同时执行的代码。

当然,也可以添加更多的线程去驱动更多的任务,如下例子可以看到所有任务彼此之间是如何互相呼应的:

public class ManyDemo {
	public static void main(String[] args) {
		for (int i = 0; i < 3; i++) {
			Demo demo = new Demo();
			Thread thread = new Thread(demo);
			thread.start();
			System.out.println("---Thread---");
		}
	}
}

输出结果:

输出结果说明不同任务的执行在线程被换进换出时混在了一起。这种交换是由线程调度器自动控制的。这个例子一次运行的结果可能与另一次运行的结果不同,因为线程机制是非确定性的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值