程序,进程,线程、协程 + {并发,并行} + {同步,异步} + 回调、轮询、阻塞

程序:

       程序的本质是初始的数据加一些指令,是数据跟指令的集合,是有序代码的集 合。程序的指令在代码里面相当于一个函数,调用一个函数相当于向程序发出一条指令,数据就是一些变量,变量就是用来保存数据的。程序本身是没有生命周期的,只是存在于磁盘上的一些指令集和,但程序一旦被运行起来就是进程。

进程(Process):

        进程是计算机中的程序关于某数据集合上的一次活动,是系统进行资源分配和调度的最小/基本单位。进程简单的来说就是一个正在运行的应用程序,进程是一个程序的运行状态。进程具有并发性,进程是由多道程序并发执行而引出来的。任务管理器的每一条任务就是一个进程。一个软件运行之后,它就是一个进程。启动后的进程,会依赖操作系统的调度完成生命周期的转换。由于每个进程都有独立的代码和数据空间,所以进程间的切换会有较大的开销。

 通过多次执行,一个程序可对应多个进程。

 通过调用关系,一个进程可包括多个程序。

线程(Thread):

        线程是CPU任务调度和程序执行的最小单位,线程是在进程下执行的线程是属于进程的。一个进程中可以包含多个线程,这些线程可以并发运行,进程要比线程消耗更多的计算机资源,进程之间不会相互影响,但是如果一个线程挂掉了,将导致整个进程都挂掉!线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。线程是被CPU并发和并行在同时执行。每个线程都有自己独立的运行栈和程序计数器,线程间切换的开销小。

         CPU在同一时刻,只能在某一个线程上执行任务!多个线程可以在同一个进程中并发执行其实就是CPU快速的在不同的线程之间切换,也就是说,当前运行的线程在任何时候都有可能被挂起(也就是等待状态),以便另外一个线程可以运行

         线程就是应用软件中互相独立的,又可以同时运行的功能。如果说这样互相独立的,又可以同时运行的功能比较多,就形成了多线程。

          线程在执行的时候,是具有随机性的,CPU的执行权有可能随时会被其他的线程给抢走!

          线程在睡眠的时候就失去执行权了!线程睡眠的时候,CPU的执行权会被其他线程给抢走!

  • 在没有使用多线程的情况下,它一定是个单任务程序/单线程程序,只有一个执行通道。
  • 程序启动时可以执行多个任务,这就是多任务程序。

进程和线程的区别:

  1. 线程在进程的内部,它不能独立执行,必须依存于进程中,由进程提供多个线程的执行控制,进程和线程都可以并发的执行。
  2. 一个进程运行后至少有一个线程
  3. 一个进程可以包含多个线程,但是一个进程至少需要有一个线程,否则这个进程是没有意义的!
  4. 进程之间不能共享资源,但线程可以
  5. 系统创建进程需要为该进程重新分配系统资源,而创建线程则容易的多,因此使用线程实现多任务并发比多进程的效率高

协程: 

  • 又称微线程,是一种用户态的轻量级线程,一个线程可以有多个协程,协程的调度完全由用户控制,也就是在用户态执行,协程拥有自己的寄存器、上下文和栈,协程调度切换时,将寄存器、上下文和栈保存到线程的堆区,在切回来的时候,恢复先前保存的寄存器、上下文和栈,直接操作栈则基本没有内核切换的开销,所以协程的上下文切换非常快。
  • 协程抽象于线程之上,协程需要线程来承载运行,与线程相比,协程占用资源少,由用户调度,切换开销小。

并发:

          CPU分时轮询的在执行线程在同一时刻,有多个指令在单个CPU上交替执行,实质上就是在单处理机环境下,多个程序分时交替的执行,它是通过时间片的来回切换完成的。是指两个或多个活动在同一给定的时间间隔中进行。在计算机宏观过程中,并发是执行多个程序,但是在微观过程中,处理机只执行了一个程序。并发在时间维度上是分时执行的。并发编程就是多线程编程。

并行:

       在同一时刻,有多个指令/线程在多个CPU上同时执行两个线程互不抢占CPU资源,可以同时进行,并行是真正的同时执行是指两个或多个活动在同一时刻/同一时间点中进行。并行依赖于CPU的处理能力同一个时刻同时在执行叫并行。在同一个时刻上,同时有多个线程被CPU处理并执行。

逻辑处理器:

            逻辑处理器是12,每次只能处理12条线程,就是意味着同时能够并行12个线程。能同时执行多少个程序,逻辑处理器越大,意味着计算机能够并行的程序越多!

同步:

  • 发出一个调用之后,在没有得到结果之前,该调用就不可以返回,一直等待必须等待该调用{任务、操作、方法}执行完毕后才能继续执行下一步。
  • 同步操作会导致当前线程阻塞,无法充分利用CPU处理器资源。

异步:

  • 调用在发出之后,不用等待返回结果,该调用直接返回,可以继续执行其它操作,最后再获取任务的结果。

  • 异步操作的优势在于它可以在执行耗时操作的同时,允许我们去执行其它操作,例如处理其它任务、响应用户的交互等。

  • 异步任务可以将执行结果封装到一个对象中,我们可以通过回调、轮询或者阻塞等方式获取任务的执行结果。

  • 在编程中,异步任务通常用于处理一些耗时的操作,例如:网络请求、文件读写、数据库查询等。通过将这些操作放入异步任务中,我们可以避免主线程的阻塞,提高程序的并发性和响应能力。

  • 在Java中,异步任务可以通过多线程、线程池、Future/FutureTask以及CompletableFuture等机制来实现,这些机制可以帮助我们创建异步任务,提交异步任务到执行器Executor中,并在需要获取任务的结果,实现高效的异步编程。

当涉及异步编程时,常用的三种获取异步任务结果的方式是回调、轮询和阻塞,它们用于在异步任务完成后获取结果。

  1. 回调(Callback):回调是一种通过定义回调函数,在异步任务完成时进行回调并处理结果的方式。将回调函数传递给异步任务,在任务执行完成后,异步任务调用该回调函数并将结果作为参数传入。这样,我们就可以在回调函数中处理结果。回调适用于需要异步任务执行完成后执行一些特定逻辑的情况,例如:处理响应数据、更新UI等。

  2. 轮询(Polling):轮询是指定期地查询异步任务的状态,看是否已经完成并获取结果。在任务未完成时反复查询其状态,直到任务完成或达到超时条件。轮询适用于无法立即获得任务结果,需要重复检查任务状态的场景。

  3. 阻塞(Blocking):阻塞是指在获取异步任务结果时,当前线程会被阻塞,直到任务完成并返回结果后才能继续执行。当我们调用阻塞方法后,线程会一直等待,直到任务完成。阻塞适用于在获取任务结果时无法进一步处理其它事务,需要等待任务结果完成后才能进行下一步操作的场景。

涉及回调的异步编程Demo:

package com.gch.callback;

/**
   定义回调接口Callback
 */
public interface Callback {
    /** 定义回调方法 */
    void onComplete(String result);
}
package com.gch.callback;
/**
   定义异步任务类AsyncTask
 */
public class AsyncTask {
    /**
     * 执行异步任务的方法 => 模拟了一个耗时的异步任务
     * @param callback => Callable回调接口的对象,表示任务完成后的回调。
     */
    public void doAsync(Callback callback){
        new Thread(()->{
            // 执行异步任务
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            // 模拟任务完成并传递结果
            String result = "Async Task Result...";
            // 在异步任务完成后,调用回调对象的onComplete方法,并将结果传递给回调方法进行处理
            callback.onComplete(result);
        }).start();
    }
}
package com.gch.callback;

/**
   主程序中使用回调来处理异步任务的结果
 */
public class Main {
    public static void main(String[] args) {
        // 创建异步任务对象
        AsyncTask asyncTask = new AsyncTask();

        // 调用吧doAsync()方法执行异步任务并传入一个匿名内部类作为回调对象
        asyncTask.doAsync(new Callback() {
            @Override
            public void onComplete(String result) {
                // 处理异步任务的结果
                System.out.println("Async Task Result => " + result );
            }
        });

        // 主线程继续执行其它操作
        System.out.println("Main Thread Continues...");
    }
}

     

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Surpass余sheng军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值