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

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

? 作者:知识浅谈,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() :表示用来查看中断标志但不抹去中断标志

?总结

发表评论

相关文章