8

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

 1 year ago
source link: https://blog.51cto.com/u_13794952/5657014
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
库调多了 都忘了最基础的概念 - 进程 / 线程篇_信号量

🍁 作者:知识浅谈,CSDN博客专家,阿里云签约博主,InfoQ签约博主,华为云云享专家
📌 擅长领域:全栈工程师、爬虫、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() :表示用来查看中断标志但不抹去中断标志

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK