共计 2536 个字符,预计需要花费 7 分钟才能阅读完成。
线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
进程(Process)是计算机中已运行程序的实体。进程为曾经是分时系统的基本运作单位。
一个进程可以有很多线程,每条线程并行执行不同的任务。
示例代码:
(来自慕课网的代码实例)
- 主类:
import java.io.*;
public class Stage extends Thread {public static void main(String[] args) {new Stage().start();}
public void run(){System.out.println("欢迎观看隋唐演义");
try {Thread.sleep(1000);
} catch (InterruptedException e1) {e1.printStackTrace();
}
System.out.println("大幕徐徐拉开");
try {Thread.sleep(1000);
} catch (InterruptedException e1) {e1.printStackTrace();
}
System.out.println("话说隋朝末年,隋军与农民起义军杀得昏天黑地...");
ArmyRunnable armyTaskOfSuiDynasty = new ArmyRunnable();
ArmyRunnable armyTaskOfRevolt = new ArmyRunnable();
/**
* 创建两个线程
*/
Thread armyOfSuiDynasty = new Thread(armyTaskOfSuiDynasty,"隋军");
Thread armyOfRevolt = new Thread(armyTaskOfRevolt,"农民起义军");
/**
* 启动线程,让军队开始作战
*/
armyOfSuiDynasty.start();
armyOfRevolt.start();
try {Thread.sleep(1000);
} catch (InterruptedException e) {e.printStackTrace();
}
System.out.println("正当双方激战正酣,半路杀出了个程咬金");
Thread mrCheng = new KeyPersonThread();
mrCheng.setName("程咬金");
System.out.println("程咬金的理想就是结束战争,使百姓安居乐业!");
/**
* 停止前两个线程
*/
armyTaskOfSuiDynasty.keepRunning = false;
armyTaskOfRevolt.keepRunning = false;
try {Thread.sleep(2000);
} catch (InterruptedException e) {e.printStackTrace();
}
mrCheng.start(); // 开始第三个线程
try {mrCheng.join(); // 新进程加入,join() 方法会在该线程结束之前一直占用 CPU} catch (InterruptedException e) {e.printStackTrace();
}
System.out.println("战争结束,人民安居乐业,程先生实现了积极的人生梦想,为人民作出了贡献!");
System.out.println("谢谢观看隋唐演义,再见!");
}
}
- 辅助类:
class ArmyRunnable implements Runnable {
volatile boolean keepRunning = true; // volatile 单独说明
@Override
public void run() {while(keepRunning){for(int i=0;i<5;i++){System.out.println(Thread.currentThread().getName()+"进攻对方["+i+"]");
Thread.yield(); // yield() 方法单独说明
}
}
System.out.println(Thread.currentThread().getName()+"结束了战斗!");
}
}
class KeyPersonThread extends Thread {public void run(){System.out.println(Thread.currentThread().getName()+"开始了战斗!");
for(int i=0;i<10;i++){System.out.println(Thread.currentThread().getName()+"左突右杀, 攻击隋军...");
}
System.out.println(Thread.currentThread().getName()+"结束了战斗!");
}
}
join()
方法的详细说明:
- 在“主线程 main”中通过 new ThreadA(“t1”) 新建“线程 t1”。接着,通过 t1.start() 启动“线程 t1”,并执行 t1.join()。
- 执行 t1.join()之后,“主线程 main”会进入“阻塞状态”等待 t1 运行结束。“子线程 t1”结束之后,会唤醒“主线程 main”,“主线程”重新获取 cpu 执行权,继续运行。
volatile
变量的说明:
- (适用于 Java 所有版本)读和写一个
volatile
变量有全局的排序。也就是说每个线程访问一个volatile
作用域时会在继续执行之前读取它的当前值,而不是(可能)使用一个缓存的值。(但是并不保证经常读写volatile
作用域时读和写的相对顺序,也就是说通常这并不是有用的线程构建)。 - (适用于 Java5 及其之后的版本)
volatile
的读和写建立了一个 happens-before 关系,类似于申请和释放一个互斥锁。
yield()
方法的说明:
会使当前线程由执行状态变为让步状态,但不代表下次执行的线程必然是其它的线程,该方法执行后当前线程会处于竞争状态,因此下次执行的线程依然可能是上次执行的线程(这里假设各个线程优先级相同)。
正文完
发表至: java
2019-11-11