- 何为线程
- 单线程与多线程,Thread 类,run 方法,和start 方法
- 线程的启动
- Thread 类,Runnable 接口
- 线程的共享互斥
- synchronized 方法,synchronized 语句和锁定
- 线程的协调
- Wait set,wait 方法,notify 方法和 notifyAll 方法
明为追踪处理流程,实则追踪线程
1.单线程程序 该程序的处理流程从头到尾就好像只有一条线。
2.多线程程序 由一个以上的线程所构成的程序成为多线程。
1)常用范例- GUI 应有程序
- 比较费时的 I/O 处理
- 多个客户端
MyThread 类
public class MyThread extends Thread{
public void run(){
...
}
}
2)启动新线程
Main 类
public class Main{
public class static void main(String[] args){
MyThread w = new MyThread(); // 实例化线程 并带入变量 w 中
w.start(); // 启动线程 w,并调用 run()
......
}
}
二 、线程的启动
1.利用 Thread 类的子类
java.lang.Thread
过程:建立 Thread 字类,建立其实例,再调用 start 方法。
2.利用 Runnable 接口Runnable 是 java.lang Package 里的接口
声明方法
public interface Runnable{
public abstract void run();
}
// 已实现的 Runnable 接口,必须实现 run方法,若未实现 run 方法,则变为抽象类
调用方法
new Thread(new MyRunnable("...")).start();
过程:建立一个实现了 Runnable 接口的类,将该实例传给 Thread 的构造器,再调用 start 方法。
三、线程的暂时停止和唤醒 sleep() 停止线程Thread.sleep(1000); //当前线程停止约1000ms(约1s) //精密的控制方式: 设置 ns 单位 Thread.sleep(ms,ns); // ns (10^-9s)interrupt() 唤醒线程
Thread.interrupt();四、线程的共享互斥
多个线程同时运行时需要“红绿灯”,进行“交通管制”。通常被称为共享互斥或互斥控制,英文:mutual exclusion。java处理此问题时使用 synchronized 关键字。
1.synchronized 方法 (锁) 当一个方法加上 synchronized 关键字声明后,就可以一次只让该方法的一个线程运行,这种方法被称为synchronized 方法。
1)格式同一实例的 synchronized 方法,一次只执行一个。执行完后会释放锁定。
一个实例有一个相对锁定。
锁定:正在执行的 synchronized 方法的状态,会使同一实例下的其他 synchronized 方法等待线程。
监视(monitor):线程互斥的架构成为监视,而获取锁定有时也称持有监视。
public synchronized void function(){
...
}
2.synchronized 阻挡(语句)
当只需要启动方法的一部分线程,而非整个方法时,可以使用 synchronized 阻挡,便可以将获取锁定的实例传达给“表达式”部分。
1)格式synchronized(表达式){
...
}
2)synchronized 实例方法和 synchronized 阻挡
synchronized 实例方法
synchronized void method(){方法体一;方法体二;}
synchronized 阻挡
void nethod(){
synchronized (this){方法体一;}
方法体二;
}
3)synchronized 类方法和 synchronized 阻挡功能上:方法体一同样属于 synchronized 方法。
也就是说,synchronized 实例方法是使用 this 锁定去实现线程的共享互斥。
synchronized 类方法
class Something{
static synchronized void method(){方法体一;方法体二;}
}
synchronized 阻挡
class Something{
static void method(){
synchronized (Something.class){方法体一;}
方法体二;
}
}
五、线程的协调 1.wait set —— 线程的休息室功能上:方法体一同样属于 synchronized 方法。
也就是说,synchronized 类方法是使用该类的对象的锁定去实现线程的共享互斥。
Something.class 是对应 Something 类的 java.lang.Class 的实例 。
wait set 是一个在执行该实例方法的 wait 方法后操作停止的线程的集合。
wait set 是一个虚拟的概念。
执行 wait 方法,线程进入 wait set,以下方法可退出 wait set:
2.wait 方法 —— 把线程放入 wait set有其他线程以 notify 方法唤醒该线程;
有其他线程以 notifyAll 方法唤醒该线程;
有其他线程以 interrupt 方法唤醒该线程;
wait 方法已到期。
使目前的线程暂时停止执行,进入实例 obj 的 wait set。
obj.wait(); // 称为:线程在 obj 上 wait
3.notify 方法 —— 从 wait set 拿出线程实例方法中 wait(); 其意义等同于 this.wait();
欲执行 wait(),线程需获取锁定
进入 wait set 的线程会释放锁定
使用 notify(通知)方法时,从 obj 的 wait set 里拿出一个线程。
obj.notify();
4.notifyAll 方法 —— 从 wait set 拿出所有线程 (推荐使用)使用 notify() 唤醒的线程会等待继续进行 wait() 后面的操作;
执行notify() 的线程释放锁定后,其才有可能获取锁定。
欲执行 notify(),线程需获取锁定;
若一个实例 obj 的 wait set 内有多个等候的线程,则由 java 处理系统决定。
唤醒所有留在 obj 实例的 wait set 里的线程。
obj.notifyAll(); notifyAll(); //将方法的实例中所有 wait set 里的线程唤醒
5.没有锁定的方法调用 wait() notify() notifyAll()实例方法中 notifyAll(); 其意义等同于 this.notifyAll();
欲执行 notifyAll(),线程需获取锁定;
使用 notifyAll() 唤醒的线程都会等待继续进行 wait() 后面的操作;
执行notifyAll() 的线程释放锁定后,其中一个才有可能获取锁定。
会抛出异常 java.lang.IllegalMonitorStateException。
六、线程的状态转移


