🍁 作者:知识浅谈,CSDN博客专家,阿里云签约博主,InfoQ签约博主,华为云云享专家
📌 擅长领域:全栈工程师、爬虫、ACM算法
💒 公众号:知识浅谈
🔥 联系方式vx:zsqtcc
温馨提醒:此文涉嫌过度分享干货,请仔细阅读
🤞这次都给他拿下🤞
正菜来了⛳⛳⛳
🎈进程和线程有什么区别?
进程:进程是一个程序的运行,是资源的分配单位,如:QQ的运行。
线程:线程是一串指令码在cpu的运行,是cpu的调度单位。
- 进程具有自己的资源,线程占用的是进程的资源。
- 进程的上下文切换比较复杂,线程的上下文切换较为容易,因为进程切换要涉及虚拟地址空间的切换,而线程不涉及。
- 进程的通信:管道,队列,信号量,线程的通信:共享内存,如Object的wait notify,重入锁,semophone信号量,counntdown。
🎈有哪些创建线程的方法?推荐使用哪种?
- 通过继承Thread的方式创建线程
重写run方法,
调用start()方法开启一线程并执行 - 实现Runnable方法
重写run方法,创建一个子类对象
传递给Thread的对象,并调用start运行。 - 实现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()); } }
- 使用线程池
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
转换过程:
- 首先new之后,状态为New
- 调用start之后状态为Runnable
- 调用wait() join()之后状态为Waiting
- 调用wait(time),sleep(time) 之后状态为TimeWaiting
- Block这个转台比较特殊,是因为争夺monitor锁阻塞的状态
如刚开始synchronized获取锁之后,调用wait()释放锁,然后又被其他线程调用notify()唤醒,但是此刻锁被其他线程占用,当前被唤醒的线程就是Blocked状态 - 线程执行结束之后的状态为Terminated
🎈为什么wait和notify必须放在synchronized中?
wait:因为wait是用来释放锁的,释放锁之前当前线程需要先获取锁。
notify:这个是用来唤醒waitset中的线程,你要唤醒别人,首先自己得有锁并且将要结束,采取唤醒别人。
所以两个都需要在有锁的状态下进行,而synchronized就是用来获取锁的
🎈sleep方法和wait方法有什么区别?
老生常谈了。
从几个方面来说吧
- sleep属于关键字,wait属于API
- sleep是Thread中的方法,而wait是Object中的方法
- sleep可以在任何代码中执行,但是wait只能在同步代码块中执行
- sleep按照规定的时间唤醒,但是wait可以使用notify,notifyall唤醒还可以设置时间自动唤醒
- 两个都可被interrrupt中断
🎈如何正确停止线程?
像之前的stop() suspend()这两种停止线程和悬挂线程都是弃用的状态,因为这两个是强制暂停和挂起线程的,如果其他线程要等待强制停止和挂起的线程的结果,像这种直接断掉,就一直等不到结果就会出现问题。
我们使用interrrupt()方法来中断,当然不是真正的中断,是把线程中断标志置为true,然后在要停止的线程中去查看中断标志,如果为true就结束线程。
这里有个主义的点就是,interrupt(),interrupted(),isInterrupted()
- interrupt():表示用来把中断标志置为true
- interrupted():表示用来查看中断标志并抹去中断标志就是变为false
- isInterrupted() :表示用来查看中断标志但不抹去中断标志