引言
- 一 个 程 序 = 并 发 任 务 1 + 并 发 任 务 2 + … … + 并 发 任 务 n = 线 程 1 + 线 程 2 + … … . . + 线 程 n 一个程序=并发任务1+并发任务2+……+并发任务n=线程1+线程2+……..+线程n 一个程序=并发任务1+并发任务2+……+并发任务n=线程1+线程2+……..+线程n
- “任务”是由于并行计算理论引入的新概念,表示相对独立的可并发的程序模块
- 线程的出现,使得一个进程可以有多个线程
多线程并发
- 操作系统中同时运行多个程序,每个程序是一个进程
- 一个程序中人为调用其他外部程序,也会在操作系统中形成一个独立的进程
- 基本上一程序对一进程的格局被保留下来
- 所以程序间的交互在研究领域被成为:进程通讯
- 由于现代软件环境中,程序间交互频繁,一般包括**“本地交互”和“远程交互”**
创建任务和线程
任务类
Java中每个任务都是一个Runnable接口的实例
TaskClass task = new TaskClass(…);
public class TaskClass implements Runnable{
线程类
Thread thrd = new Thread(task);
启动线程: thrd.start();
任务和线程程序示例
//任务
public class TaskTreadDemo{
public static void main(String[] args) {
PrintChar t1 = new PrintChar('a',50);
PrintChar t2 = new PrintChar('b',50);
Thread th1 = new Thread(t1);
Thread th2 = new Thread(t2);
th1.start();
th2.start();
}
}
//线程
public class PrintChar implements Runnable {
private char charToPrint;
private int times;
public PrintChar(char c, int t) {
charToPrint = c;
times = t;
}
public void run() {
for(int i=0 ;i<times;i++) {
System.out.print(charToPrint);
//JOptionPane.showConfirmDialog(null,charToPrint);
}
}
}
Thread类
方法 | 用法 |
---|---|
Start() | 启动 |
isAlive() | 检测当前线程是否在运行 |
setPriority(int p) | 设定优先级 p从1到10 |
Join() | 等待线程结束API |
sleep(long m) | 使当前线程休眠m毫秒 |
Yield() | 挂起当前线 |
Interrupt | 中断线程 |
GUI事件分发线程
- 确保事件处理不被打断,因为在图形环境中事件是最小执行单位
- 一般情况下EventDispatcher运行在底层,编码中不用(Java自动保障)
- 特殊情况下需要确保一段代码不会被其他线程打断(往往是为了避免死锁),所以需要以明码方式触发EventDispatcher
- EventDispatcher触发方式:
通过Javax.swing.SwingUtilities类中使用静态方法invokelater()和invokeAndWait()
e.g.
SwingUtilities.invokelater(new Runnable(){
public void run(){
//run something }
});
Join方法
- 主线程生成并起动了子线程,
- 而子线程里要进行大量的耗时的运算,
- 当主线程处理完其他的事务后,
- 需要用到子线程的处理结果,
- 这个时候需要用join()等待子线程运行结束。
注:join()底层使用 wait() 方法来实现
死锁的必要条件
- 互斥条件:一个资源每次只能被一个进程使用。
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。