java中的进程和线程
2023-06-16 本文已影响0人
我要离开浪浪山
1、什么是进程?
进程是程序运行资源分配的最小单位
2、什么是线程?
线程是 CPU 调度的最小单位,必须依赖于进程而存在
3、什么是并发?
- 并发是指多个任务在同一时间段内执行的能力,这些任务可以是线程、进程、协程等。
- 在并发编程中,不同的任务之间相互独立,可以同时或交替地执行。
- 并发编程的目的是提高程序的性能和效率,同时减少系统的响应时间。
- 并发编程中常见的问题包括竞态条件、死锁、饥饿等问题。
- 为了解决这些问题,需要使用同步机制,如锁、信号量、条件变量等。
4、什么是并行?
- 并行是指多个任务在同一时刻执行的能力,这些任务可以是线程、进程、协程等。
- 在并行计算中,不同的任务之间相互独立,可以同时执行。
- 并行计算的目的是提高计算机系统的处理能力,从而加速任务的处理速度。
5、线程的启动
启动线程的方式有:
- 1、X extends Thread;,然后 X.start
- 2、X implements Runnable;然后交给 Thread 运行
6、Thread 和 Runnable 的区别
- Thread 才是 Java 里对线程的唯一抽象,
- Runnable 只是对任务(业务逻辑)的抽象。
- Thread 可以接受任意一个 Runnable 的实例并执行。
7、stop
暂停、恢复和停止操作对应在线程 Thread 的 API 就是 suspend()、resume() 和 stop()。
但是这些 API 是过期的,也就是不建议使用的。
不建议使用的原因主要有:
- 以 suspend()方法为例,在调用后,线程不会释放已经占有的资源(比如
锁), - 而是占有着资源进入睡眠状态,这样容易引发死锁问题。
- 同样,stop()方法在终结一个线程时不会保证线程的资源正常释放,通常是没有给予线程完成资源释放工作的机会,因此会导致程序可能工作在不确定状态下。
- 正因为 suspend()、resume()和 stop()方法带来的副作用,这些方法才被标注为不建议使用的过期方法。
8、中断
- 安全的中止则是其他线程通过调用某个线程 A的
interrupt()
方法对其进行中断操作,中断好比其他线程对该线程打了个招呼,“A,你要中断了”,不代表线程 A会立即停止自己的工作,同样的 A线程完全可以不理会这种中断请求。因为 java里的线程是协作式的,不是抢占式的。线程通过检查自身的中断标志位是否被置为 true来进行响应,
- 线程通过方法
isInterrupted()
来进行判断是否被中断,也可以调用静态方法Thread.interrupted()
来进行判断当前线程是否被中断,不过Thread.interrupted()
会同时将中断标识位改写为 false。
- 如果一个线程处于了阻塞状态(如线程调用了
thread.sleep、thread.join、thread.wait等
),则在线程在检查中断标示时如果发现中断标示为true
,则会在这些阻塞方法调用处抛出InterruptedException异常
,并且在抛出异常后会立即将线程的中断标示位清除,即重新设置为 false。
注意:处于死锁状态的线程无法被中断
9、深入理解 run()和 start()
Thread
类是Java里对线程概念的抽象,可以这样理解:我们通过new Thread()
其实只是new 出一个 Thread 的实例
,还没有操作系统中真正的线程挂起钩来。
只有执行了start()方法后
,才实现了真正意义上的启动线程。start()方法
让一个线程进入就绪队列等待分配cpu
,分到 cpu 后才调用实现
的run()
方法,start()
方法不能重复调用,如果重复调用会抛出异常。- 而
run 方法
是业务逻辑实现的地方,本质上和任意一个类的任意一个成员方
法并没有任何区别,可以重复执行,也可以被单独调用。
10、yield()方法:
- 使当前线程让出 CPU 占有权,但让出的时间是不可设定的。也
不会释放锁资源。
注意:并不是每个线程都需要这个锁的,而且执行 yield( )的线
程不一定就会持有锁,我们完全可以在释放锁后再调用 yield 方法。
所有执行 yield()的线程有可能在进入到就绪状态后会被操作系统再次选中
马上又被执行。
11、join 方法
把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行。
比如在线程 B 中调用了线程 A 的 Join()方法,直到线程 A 执行完毕后,才会继续
执行线程 B。(此处为常见面试考点)
12、线程的优先级
在 Java 线程中,通过一个整型成员变量 priority 来控制优先级,优先级的范
围从 1~10,在线程构建的时候可以通过 setPriority(int)方法来修改优先级,默认
优先级是 5,优先级高的线程分配时间片的数量要多于优先级低的线程。
13、守护线程
- Daemon(守护)线程是一种支持型线程,因为它主要被用作程序中后台调度以及支持性工作。这意味着,当一个 Java 虚拟机中不存在非 Daemon 线程的时候,Java 虚拟机将会退出。可以通过调用 Thread.setDaemon(true)将线程设置为 Daemon 线程。我们一般用不上,比如垃圾回收线程就是 Daemon 线程。
- Daemon 线程被用作完成支持性工作,但是在 Java 虚拟机退出时 Daemon 线程中的 finally 块并不一定会执行。在构建 Daemon 线程时,不能依靠 finally 块中
的内容来确保执行关闭或清理资源的逻辑。
14、对象锁和类锁:
对象锁:
是用于对象实例方法,或者一个对象实例上的,类锁:
是用于类的静态方法或者一个类的 class 对象上的。
我们知道,类的对象实例可以有很多个,但是每个类只有一个 class 对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。
但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,类锁其实锁的是每个类的对应的 class 对象。类锁和对象锁之间也是互不干扰的。