程序是对数据描述与操作的代码的集合,如Office中的Word,暴风影音等应用程序。
进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程。
进程的特点:
①:进程是系统运行程序的基本程序。
②:每一个进程都有自己独立的一块内存空间、一组资源资源。
③:每一个进程的内部数据和状态都是完全独立的。
进程包括系统进程(有操作系统内部建立的进程)和用户进程(由用户程序建立的进程)。
每个进程中,至少建立一个线程,来作为这个程序运行的入口点。
在一个进程中同时运行了多个线程,用来完成不同的工作,则称为“多线程”。
多线程的好处:
①:充分利用CPU的资源:执行单线程是,若程序发生阻塞,CPU可能处于空闲,造成资源浪费;而使用多线程可以在发生阻塞时运行其他线程,大大提高利用率
②:简化编程模型:一个即长又复杂的进程可以考虑分为多个线程,成为几个独立的运行部分。
③:带来良好的用户体验:多个线程交替执行,减少或避免因程序阻塞或意外情况造成的响应过慢现象,降低了用户等待的概率。
Thread类的常用方法
Thread(): 分配新的Thread对象
Thread(Runnable target): 分配新的Thread对象,target为run()方法被调用的对象
Thread(Runnable target,String name): 分配新的Thread对象,target为run()方法被调用的对象,name为新线程的名称
void run(): 执行任务操作的方法
void start(): 使该线程开始执行,Java虚拟机调用该线程的run()方法
void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
String getName() 返回该线程的名称。
int getPriority() 返回线程的优先级。
void setPriority(int newPriority) 更改线程的优先级。
static Thread currentThread(): 返回当前正在执行的线程对象的引用
boolean isAlive(): 测试线程是否处于活动状态
void join() 等待该线程终止。
void interrupt() 中断线程。
void yield() 暂停当前正在执行的线程对象,并执行其他线程。
boolean isDaemon() 测试该线程是否为守护线程。
void setDaemon(boolean on) 将该线程标记为守护线程或用户线程。
void setName(String name) 改变线程名称,使之与参数 name 相同。
从Object类继承来的方法 void notify() void wait()
主线程
在Java程序启动时,一个线程立刻运行,该程序通常称为程序的主线程。
①:它是产生其他子线程的线程。
②:通常它必须最后完成执行,因为它执行各种关闭动作。
使用一个线程的过程,分为四个步骤:
①:定义一个线程,同时指明这个线程所要执行的代码,即期望完成的功能。
②:创建线程对象。
③:启动线程
④:终止线程。
创建线程类的两种方法:一个是继承Thread类,另一个是实现Runnable接口。
继承Thread类:
1、扩展java.lang.Thread类。
此类中有个run()方法,应该注意其用法:
public void run()
如果该线程是使用独立的Runnable运行对象构造的,则调用该Runnable对象的run方法;否则,该方法不执行任何操作并返回。
①:编写简单,可直接操作线程。
②:适用于单继承。
注意:已启动的线程对象不能再次调用start()方法,否则会抛出IllegalThreadStateException异常(线程没有处于请求操作所需要的适当状态时抛出的异常)。
线程实例调用start()方法和直接调用run()方法有什么区别?
start()是启动程序,run()是调用实例方法。
实现Runnable接口
2、实现java.lang.Runnable接口。
void run()
使用实现接口Runnable的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的run方法。
方法run的常规协定是,它可能执行任何所需的操作。
①:避免单继承局限性
②:便于共享资源
一个类可以通过实现Runnable接口并实现其run()完成线程的所有活动,已实现的run()方法称为该线程对象的线程体。
例题1:创建两个线程,每个线程均输出20次消息数字、“你好”、线程名。
/** * 继承Thread的类 * @author 颢6 * */ public class MyThread extends Thread{ public void run(){ for (int i = 1; i <=20; i++) { System.out.println("你好,来自线程"+Thread.currentThread().getName()+":"+i); } } }
/** * 测试Thread类实现的多线程程序 * @author 颢6 * */ public class TestStart { public static void main(String[] args) { MyThread mt1=new MyThread(); mt1.start(); Thread t1=new Thread(new MyThread()); t1.start(); } }
例题2:使用实现Runnable接口的方式创建线程类,修改测试类
/** * 实现Runnable接口的类 * @author Administrator * */ public class MyThread implements Runnable{ public void run() { for (int i = 1; i <=20; i++) { System.out.println(i+".你好,来自线程"+Thread.currentThread().getName()); } } }
/** * 测试Runnable类的实现多线程程序 * @author 颢6 * */ public class Test { public static void main(String[] args) { Thread myS=new Thread(new MyThread()); myS.start(); } }
线程的状态
任何线程一般都具有五种状态,即创建、就绪、运行、阻塞、死亡状态。
创建状态:在程序中用构造方法创建了一个线程对象后,新的线程对象就处于创建状态。
就绪状态:线程创建之后,就可以通过调用start()方法启动线程,即进入就绪状态。
运行状态:当就绪状态的线程获得CPU资源是,即可进入运行状态,执行run()方法。
阻塞状态:一个正在运行的线程因某种原因不能继续运行时,进入阻塞状态。
①:由于线程优先级比较低,因此它不能获得CPU资源。
②:使用sleep()方法使线程休眠。
③:通过调用wait()方法,是线程等待。
④:通过调用yield(),线程显式出让CPU控制权。
⑤:线程由于等待一个文件,I/O事件被阻塞。
死亡状态:一个线程的run()方法运行完毕,则进入死亡状态。