文章目录
一 进程与线程
1.1 操作系统与进程
程序是一段静态的代码,它是应用软件执行的蓝本。
进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。
现代操作系统可以同时管理一个计算机系统中的多个进程,即可以让计算机系统中的多个进程轮流使用CPU资源。
1.2 进程与线程
线程是比进程更小的执行单位,一个进程在其执行过程中,可以产生多个线程,形成多条执行线索,每条线索,即每个线程也有它自身的产生、存在和消亡的过程。
线程间可以共享进程中的某些内存单元(包括代码与数据),线程的中断与恢复可以更加节省系统的开销。
二 Java中的线程
2.1 Java的多线程机制
Java语言的一大特性点就是内置对多线程的支持。
Java虚拟机快速地把控制从一个线程切换到另一个线程。这些线程将被轮流执行,使得每个线程都有机会使用CPU资源。
每个Java应用程序都有一个缺省的主线程。
JVM一直要等到Java应用程序中的所有线程都结束之后,才结束Java应用程序 。
2.2 线程的状态与生命周期
新建的线程在它的一个完整的生命周期中通常要经历如下的四种状态:
1.新建: 当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态。
2.运行 :线程必须调用start()方法(从父类继承的方法)通知JVM,这样JVM就会知道又有一个新一个线程排队等候切换了。一旦轮到它来享用CPU资源时,此线程的就可以脱离创建它的主线程独立开始自己的生命周期了。此时,程序通过重写的run()方法执行该线程的具体使命。
启动线程为什么不调用run(),调用start()
start()启动线程, JVM调用run()
start()方法最终执行的是start0(),是本地方法,C++写出来,和操作系统交互,启动线程是操作系统的事情
Thread类start方法源码:
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
private native void start0();
3.中断:有4种原因的中断:
◆ JVM将CPU资源从当前线程切换给其他线程,使本线程让出CPU的使用权处于中断状态。
◆线程使用CPU资源期间,执行了sleep(int millsecond)方法,使当前线程进入休眠状态。
◆线程使用CPU资源期间,执行了wait()方法。
◆线程使用CPU资源期间,执行某个操作进入阻塞状态。
4.死亡 :处于死亡状态的线程不具有继续运行的能力。线程释放了实体。
2.3 线程调度与优先级
处于就绪状态的线程首先进入就绪队列排队等候CPU资源,同一时刻在就绪队列中的线程可能有多个。Java虚拟机(JVM)中的线程调度器负责管理线程,调度器把线程的优先级分为10个级别,分别用Thread类中的类常量表示。默认优先级为常数5
Java调度器的任务是使高优先级的线程能始终运行,一旦时间片有空闲,则使具有同等优先级的线程以轮流的方式顺序使用时间片。
三 Thread类与线程的创建
在Java语言中,用Thread类或子类创建线程对象。
3.1 使用Thread的子类
在编写Thread类的子类时,需要重写父类的run()方法,其目的是规定线程的具体操作,否则线程就什么也不做,因为父类的run()方法中没有任何操作语句。
public class 类名1 extends Thread {
//重写run()方法
public void run(){
····
}
}
调用线程的类里
类名1 test1=new 类名1();//创建线程
test1.start();//启动线程
注:运用了线程的程序在不同计算机运行或同一台计算机反复运行结果不尽相同,输出结果依赖当前CPU资源的使用情况。
3.2 使用Thread类
创建线程的另一个途径就是用Thread类直接创建线程对象。
使用Thread创建线程通常使用的构造方法是:
Thread(Runnable target)
该构造方法中的参数是一个Runnable类型的接口。
在创建线程对象时必须向构造方法的参数传递一个实现Runnable接口类的实例,该实例对象称作所创线程的目标对象,当线程调用start()方法后,一旦轮到它来享用CPU资源,目标对象就会自动调用接口中的run()方法(接口回调)。
public class TestThread{
public static void main(String args[]) {
House house = new House();
house.setWater(10);
Thread dog, cat;
dog = new Thread(house);//接口回调
cat = new Thread(house); // cat和dog的目标对象相同
dog.start();
cat.start();
}
}
public class House implements Runnable {
//实现Runnable接口类
int waterAmount; //用int变量模拟水量
public void setWater(int w) {
waterAmount=w;
}
public void run() {
int m=1;
while(true) {
if(waterAmount<=0) {
return ;</