线程基础,线程之间的共享和协作

1、ccpu核心数和线程数的关系
核心数:线程数=1:1 使用了超线程技术后变为1:2

2、cpu时间片轮转机制:又称为RR调度,会导致上下文切换

3、线程和进程
进程:程序运行资源分配的最小单位,进程内部有多个线程,会分享这个进程的资源
线程;cpu调度的最小单位,必须依赖进程而存在

4、并行和并发
并行:同一时刻,可以同时处理事情的能力
并发:与单位时间相关,在单位时间内可以处理事情的能力

5、高并发编程的意义和注意点
意义:充分利用cpu的资源、加快用户响应的时间,程序模块化,异步化
问题:线程共享资源,存在冲突;
容易导致死锁;
启用太多的线程,就有搞垮机器的可能

6、新启线程的方式
继承Thread类创建线程类
通过Runnable接口创建线程类
通过Callable和Future创建线程
通过线程池创建

7、创建线程的三种方式的对比
1、采用实现Runnable、Callable接口的方式创建多线程
优点: 线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。
缺点: 编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。
2、使用继承Thread类的方式创建多线程
优点:编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。
缺点:线程类已经继承了Thread类,所以不能再继承其他父类
3、Runnable和Callable的区别
(1) Callable规定(重写)的方法是call(),Runnable规定(重写)的方法是run()。
(2) Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
(3) call方法可以抛出异常,run方法不可以。

8、线程的五种状态
线程基础,线程之间的共享和协作_第1张图片
(1)新建
当用new操作符创建一个线程时, 例如new Thread®,线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码。
(2)就绪
一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。处于就绪状态的线程并不一定立即运行run()方法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运行线程
(3)运行状态
当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法
(4)阻塞状态
线程运行过程中,可能由于各种原因进入阻塞状态
(5)死亡
有两个原因会导致线程死亡:

  1. run方法正常退出而自然死亡,
  2. 一个未捕获的异常终止了run方法而使线程猝死。
    为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,则返回false。

9、run()和start()
Start():用来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。start方法不能被重复调用
run()方法:直接调用在当前线程中处理run方法的主体,可以重复调用

10、yield() :yield() :让出cpu的执行权,将线程从运行转到可运行状态,但是下个时间片,该线程依然有可能被再次选中运行。

11、怎么样才能让Java里的线程安全停止工作呢
stop(),resume(),suspend()已不建议使用,stop()会导致线程不会正确释放资源,suspend()容易导致死锁。
interrupt() 向当前调用者线程发出中断信号
isinterrupted() 查看当前中断信号是true还是false
interrupted() 是静态方法,查看当前中断信号是true还是false并且改为false

正常逻辑来说,调用interrupt()方法,isInterrupted()为true,线程就会退出运行。然而,线程没有停止,还在继续输出。
而且,从输出内容我们看到,线程被interrupt(),触发了一个InterruptedException异常。在异常前,中断状态true;异常后,中断状态false。
如果线程正在执行wait,sleep,join方法,你调用interrupt()方法,会抛出InterruptedException异常。而一个抛出了异常的线程的状态马上就会被置为非中断状态,如果catch语句没有处理异常,则下一次循环中isInterrupted()为false,线程会继续执行,可能你N次抛出异常,也无法让线程停止。

12、线程的优先级:取值为1~10,缺省为5,但线程的优先级不可靠,不建议作为线程开发时候的手段

13、守护线程:和主线程共死,finally不能保证一定执行

14、synchronized内置锁
对象锁,锁的是类的对象实例。
类锁 ,锁的是每个类的的Class对象,每个类的的Class对象在一个虚拟机中只有一个,所以类锁也只有一个。

15、适合于只有一个线程写,多个线程读的场景,因为它只能确保可见性。

16、线程间协作:轮询:难以保证及时性,资源开销很大

17、等待和通知
wait() 对象上的方法
notify/notifyAll 对象上的方法
应该尽量使用notifyAll,使用notify因为有可能发生信号丢失的的情况

18、join()方法
线程A,执行了线程B的join方法,线程A必须要等待B执行完成了以后,线程A才能继续自己的工作

面试点
线程在执行yield()以后,持有的锁是不释放的
sleep()方法被调用以后,持有的锁是不释放的
调动方法之前,必须要持有锁。调用了wait()方法以后,锁就会被释放,当wait方法返回的时候,线程会重新持有锁
调动方法之前,必须要持有锁,调用notify()方法本身不会释放锁的

你可能感兴趣的:(java,线程,java)