什么是线程?
线程是一个应用程序内部的顺序控制流。
线程和进程
·每个进程都有独立的代码和数据空间,进程切换的开销大。
·线程:轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
·多进程:在操作系统中能同时运行多个任务(程序)
·多线程:在同一应用程序中有多个顺序流同时执行。
线程的概念模型:
1.虚拟的CPU,由java.lang.Thread类封装和虚拟;
2.CPU所执行的代码,传递给Thread类对象;
3.CPU所处理的数据,传递给Thread类对象。
创建线程:
·Java的线程是通过java.lang.Thread类来实现的。
·每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。
多线程共享代码和数据:
·多线程之间可以共享代码和数据,如:
Runner2 r = new Runner2();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
创建线程的第二种方式:
·直接继承Thread类创建线程
如:
class Runner3 extends Thread{
public void run(){
for(int i= 0;i<30;i++){
System.out.println(i);
}
}
}
两种方法比较:
1.使用Runnable接口创建线程:
·可以将CPU、代码和数据分开,形成清晰的模型;
·线程体run()方法所在的类还可以从其他类继承一些有用的属性或方法;
·并有利于保持程序风格的一致性。
2.直接继承Thread类创建进程:
·Thread子类无法再从其他类继承
·编写简单,run()方法的当前对象就是线程对象,可直接操纵。
后台线程:
·基本概念:
后台处理(Background Processing):并发执行时,把cpu分时间片来处理
后台线程(Background Thread/Daemon Thread):守护线程,以后台方式运行的线程(次要线程)等。如垃圾回收,等cpu空闲时才启动。
用户线程(User Thread):需要处理的线程
主线程(Main Thread):main方法
子线程(Sub Thread):在主线程中又创建了的线程
·Thread类提供的相关方法:
public final boolean isDaemon() //判断指定线程是否为后台线程
public final void setDaemon(Boolean on) //将某以线程设置为后台线程
GUI线程:
·GUI程序运行过程中系统会自动创建若干GUI线程。
常见如下:
AWT-Wiondws线程
AWT-EventQueue-n线程
AWT-Shutdown线程
线程生命周期:
·新建状态
·就绪状态
·运行状态
·阻塞状态
·终止状态
线程优先级:
·线程的优先级用数字来表示,范围从1到10
·主线程的缺省优先级是5,子线程的优先级默认与其父线程相同。
Thread类提供的相关方法:
public final int getPriority();
public final void setPriority(int new Priority)//设置线程的优先级
·相关静态整型常量:
Thread.MIN_PRIORITY = 1
Thread.MAX_PRIORITY = 10
Thread.NORM_PRIORITY = 5
线程串行化:
·在多线程程序中,如果在一个线程运行的过程中要用到另一个线程的运行结果,则可进行线程的串行化处理。
·Thread类提供的相关方法:
public final void join()
public final void join(long millis)
public final void join(long millis,int nanos)
//将一个线程调用到另一个线程中
线程休眠:
·暂停执行当前运行中的线程,使之进入阻塞状态,待经过指定的“延迟时间”后再唤醒来并转入到就绪状态。
·提供的相关方法:
public static void sleep(long millis)
public static void sleep(long millis,int nanos)
线程让步:
·让运行中的线程主动放弃当前获得的CPU处理机会,但不是使该线程阻塞,而是使之转入就绪状态。
提供的方法如下:
public static void yield()
线程挂起和恢复:
·挂起——暂时停止当前运行中的线程,使之转入阻塞状态,并且不会自动恢复运行。
·恢复——使得一个已挂起的线程恢复运行。
提供的方法:
public final void suspend() //挂起一个线程
public final void resume() //恢复一个已经挂起的线程
线程互斥锁:
当需要同步运行某对象的时候,需要用到互斥锁。
线程同步通信:
·为避免死锁,在线程进入阻塞状态时应尽量释放其锁定的资源,以为其他的线程提供运行的机会。
相关方法:
public final void wait() //线程被阻塞,其他运行的线程就可以调用原先被锁定的对象
public final void notify() //解除阻塞状态
public final void notifyAll() //一下子全解除所有的阻塞状态
管道流:(用于线程间数据传输)
PipedInputStream和PipedOutputStream
可以用DataInputStream来封装。