写点什么

库调多了 都忘了最基础的概念 - 进程 / 线程篇

作者:知识浅谈
  • 2022 年 9 月 07 日
    吉林
  • 本文字数:1745 字

    阅读完需:约 6 分钟

库调多了 都忘了最基础的概念-进程/线程篇

🍁 作者:知识浅谈,InfoQ 签约博主,CSDN 博客专家,阿里云签约博主,华为云云享专家

📌 擅长领域:全栈工程师、爬虫、ACM 算法

💒 公众号:知识浅谈


温馨提醒:此文涉嫌过度分享干货,请仔细阅读🤞这次都给他拿下🤞


正菜来了⛳⛳⛳

🎈进程和线程有什么区别?

进程:进程是一个程序的运行,是资源的分配单位,如:QQ 的运行。线程:线程是一串指令码在 cpu 的运行,是 cpu 的调度单位。


  1. 进程具有自己的资源,线程占用的是进程的资源。

  2. 进程的上下文切换比较复杂,线程的上下文切换较为容易,因为进程切换要涉及虚拟地址空间的切换,而线程不涉及。

  3. 进程的通信:管道,队列,信号量,线程的通信:共享内存,如 Object 的 wait notify,重入锁,semophone 信号量,counntdown。

🎈有哪些创建线程的方法?推荐使用哪种?

  1. 通过继承 Thread 的方式创建线程重写 run 方法,调用 start()方法开启一线程并执行

  2. 实现 Runnable 方法重写 run 方法,创建一个子类对象传递给 Thread 的对象,并调用 start 运行。

  3. 实现 callable 方法重写 call 方法,创建一个子类对象,并作为 FutureTask 的参数传入然后把创建的 FutureTask 作为参数传递给 Thread 的对象,并调用 start 运行。


  class A implements Callable<String> {      @Override      public String call() throws Exception {          return "run";      }  }  public class Main {      public static void main(String[] args) throws ExecutionException, InterruptedException {          A a = new A();          FutureTask<String> vFutureTask = new FutureTask<>(a);            Thread thread = new Thread(vFutureTask);          thread.start();          System.out.println(vFutureTask.get());      }  }
复制代码


  1. 使用线程池 ExecutorService pools = Executors.newFixedThreadPool();pool.submit(实现 run 方法)

🎈为什么 start 方法不能重复调用?而 run 方法却可以?

首先 start 和 run 的区别,调用 start 的时候会先创建一个线程,然后在创建的线程中执行 run 方法,而直接调用 run 相当于在当前线程中执行 run 方法,并没有创建线程之后执行。 因为 run 方法是普通方法,start 方法是线程创建的方法,普通方法可以执行多次,但是线程只能创建一次,所以 start 方法只能调用 1 次。

🎈说一下线程生命周期,以及转换过程?

线程的生命周期状态:New,Runable,Waiting,TimeWaiting,Blocked,Terminated 转换过程:


  1. 首先 new 之后,状态为 New

  2. 调用 start 之后状态为 Runnable

  3. 调用 wait() join()之后状态为 Waiting

  4. 调用 wait(time),sleep(time) 之后状态为 TimeWaiting

  5. Block 这个转台比较特殊,是因为争夺 monitor 锁阻塞的状态如刚开始 synchronized 获取锁之后,调用 wait()释放锁,然后又被其他线程调用 notify()唤醒,但是此刻锁被其他线程占用,当前被唤醒的线程就是 Blocked 状态

  6. 线程执行结束之后的状态为 Terminated

🎈为什么 wait 和 notify 必须放在 synchronized 中?

wait:因为 wait 是用来释放锁的,释放锁之前当前线程需要先获取锁。notify:这个是用来唤醒 waitset 中的线程,你要唤醒别人,首先自己得有锁并且将要结束,采取唤醒别人。所以两个都需要在有锁的状态下进行,而 synchronized 就是用来获取锁的

🎈sleep 方法和 wait 方法有什么区别?

老生常谈了。从几个方面来说吧


  1. sleep 属于关键字,wait 属于 API

  2. sleep 是 Thread 中的方法,而 wait 是 Object 中的方法

  3. sleep 可以在任何代码中执行,但是 wait 只能在同步代码块中执行

  4. sleep 按照规定的时间唤醒,但是 wait 可以使用 notify,notifyall 唤醒还可以设置时间自动唤醒

  5. 两个都可被 interrrupt 中断

🎈如何正确停止线程?

像之前的 stop() suspend()这两种停止线程和悬挂线程都是弃用的状态,因为这两个是强制暂停和挂起线程的,如果其他线程要等待强制停止和挂起的线程的结果,像这种直接断掉,就一直等不到结果就会出现问题。我们使用 interrrupt()方法来中断,当然不是真正的中断,是把线程中断标志置为 true,然后在要停止的线程中去查看中断标志,如果为 true 就结束线程。这里有个主义的点就是,interrupt(),interrupted(),isInterrupted()


  • interrupt():表示用来把中断标志置为 true

  • interrupted():表示用来查看中断标志并抹去中断标志就是变为 false

  • isInterrupted() :表示用来查看中断标志但不抹去中断标志

🍚总结

以上就是关于进程/线程的相关知识总结。

发布于: 刚刚阅读数: 4
用户头像

知识浅谈

关注

公众号:知识浅谈 2022.06.22 加入

🍁 作者:知识浅谈,InfoQ签约作者,CSDN博客专家/签约讲师,华为云云享专家,阿里云签约博主 📌 擅长领域:全栈工程师、爬虫、ACM算法 💒 公众号:知识浅谈 🔥 联系方式vx:zsqtcc

评论

发布
暂无评论
库调多了 都忘了最基础的概念-进程/线程篇_9月月更_知识浅谈_InfoQ写作社区