现代操作系统,都可以执行多任务。多任务就是用试运行多个任务。例如 QQ可以同时对消息的收发。CPU执行代码都是一条一条顺序执行的,但是,即使是单核CPU,也可以同时运行多个任务。因为操作系统执行多任务实际上就是让CPU对多个任务轮流交替执行。
程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,可以理解为程序是包含静态代码的文件。
进程是程序的一次执行过程,是系统运行程序的基本单位。在windows系统中,每一个正在执行的exe文件或后台服务,都是一个进程,由操作系统统一管理并分配资源,因此进程是动态的。
操作系统运行一个程序,即是一个进程从创建、运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令的执行着。同时,每个进程还占有某些系统资源如CPU时间、内存空间、文件、输入输出设备的使用权。
某些进程内部还需要同时执行多个子任务。而这些子任务我们就称之为线程,线程是进程划分成的更小的运行单位。
进程和线程的关系就是:
一个进程可以包含一个或者多个线程,但至少会有一个主线程。
线程是比进程更小的执行单位(CPU的最小执行单位)。一个进程在其执行的过程中可以产生多个线程。与进程不同的是:同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或者是在各个线程之间作切换工作时,负担要比进程小的多。
单线程就是进程中只有一个线程。单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。
- public class SingleThread {
- public static void main(String[] args) {
- for (int i = 0; i < 10000; i++) {
- System.out.print(i + " ");
- }
- }
- }
由一个以上的线程组成的程序称为多线程程序。Java中,一定是从主线程开始执行(main方法)。然后在主线程的某个位置创建并启动新的线程。
- public class MultiThread {
- public static void main(String[] args) {
- // 创建2个线程
- Thread t1 = new Thread(new Runnable() {
-
- @Override
- public void run() {
- for (int i = 0; i < 10000; i++) {
- System.out.println("线程1:" + i + " ");
- }
- }
- });
- Thread t2 = new Thread(new Runnable() {
-
- @Override
- public void run() {
- for (int i = 0; i < 10000; i++) {
- System.out.println("线程2:" + i + " ");
- }
- }
- });
-
- // 启动2个线程
- t1.start();
- t2.start();
- }
- }
通过创建Thread实例,完成线程的创建。
- public class Main {
- public static void main(String[] args) {
- // Step1: main主线程执行输出
- System.out.println("main start...");
-
- // Step2: main主线程,创建子线程sub,输出字母A-Z
- Thread sub = new Thread() {
- // Step4:子线程被执行时,自动调用run()方法
- public void run() {
- for(char c='A';c<='Z';c++){
- System.out.println("子线程:" + c);
- }
- }
- };
-
- // Step3: main主线程,启动子线程sub
- sub.start();
-
- // Step4: main主线程执行输出字母的ASCII码
- for(int c ='a';c<='z';c++){
- System.out.println("main线程:" + c);
- }
- System.out.println("main end...");
- }
- }
- // 线程子类
- public class SubThread extends Thread {
- public void run() {
- for (int i = 0; i < 10000; i++) {
- System.out.println("子线程" + i + " ");
- }
- }
- }
-
- // 主线程main
- public class MultiThread {
- public static void main(String[] args) {
- //创建并启动子线程
- SubThread thd = new SubThread();
- thd.start();
-
- //主线程继续同时向下执行
- for (int i = 0; i < 10000; i++) {
- System.out.println("主线程" + i + " ");
- }
- }
- }
- // 线程执行类
- public class SubThread implements Runnable {
- public void run() {
- for (int i = 0; i < 10000; i++) {
- System.out.println("子线程" + i + " ");
- }
- }
- }
-
- // 主线程 main
- public class MultiThread {
- public static void main(String[] args) {
- //创建并启动子线程
- Thread t = new Thread(new SubThread());
- t.start();
-
- //主线程继续同时向下执行
- for (int i = 0; i < 10000; i++) {
- System.out.println("主线程" + i + " ");
- }
- }
- }
- // 实现子线程
- public class SubThread implements Callable
{ - private int begin,end;
- public SubThread(int begin,int end){
- this.begin = begin;
- this.end = end;
- }
- @Override
- public Integer call() throws Exception {
- int result = 0;
- for(int i=begin;i<=end;i++){
- result+=i;
- }
- return result;
- }
- }
子线程创建并启动
- // 子线程封装为FutureTask对象,计算1-100的累加和
- SubThread subThread1 = new SubThread(1,100);
- FutureTask
task1 = new FutureTask<>(subThread1); -
- // 子线程封装为FutureTask对象,计算101-200的累加和
- SubThread subThread2 = new SubThread(101,200);
- FutureTask
task2 = new FutureTask<>(subThread2); -
- // 分别启动两个子线程
- new Thread(task1).start();
- new Thread(task2).start();
-
- // 分别获取两个子线程的计算结果
- int sum1 = task1.get();
- int sum2 = task2.get();
-
- // 汇总计算结果
- int total = sum1 + sum2;
线程池,按照配置参数(核心线程数、最大线程数等)创建并管理若干对象。程序中如果需要线程,将一个执行任务传给线程池,线程并不会死亡,而是再次返回线程成为空闲状态,等待执行下一个任务。使用线程持可以更好的提高性能。
- // 创建固定大小的线程池
- ExecutorService threadPool = Executors.newFixedThreadPool(10);
- while (true) {
- // 提交多个执行任务至线程池,并执行
- threadPool.execute(new Runnable() {
- @Override
- public void run() {
- System.out.println("当前运行的线程名为: " + Thread.currentThread().getName());
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- });
- }