有关线程的总结

要想更好的对线程题进行编码,首先得把基础概念掌握牢固,要不等到面试的时候考官问的时候一句话也说不出来。

一.什么是进程,什么是线程,两者之间的区别与联系

进程:指操作系统中正在运行的一个程序。

线程:是进程内一个相对独立的,可调度的执行单元。

两者之间的关系:

1.一个线程只能属于一个进程,而一个进程可以包含多个线程。

2.资源分配给进程,同一进程的所有线程共享该资源。

3.处理机分给线程,即真正在处理机上运行的是线程

两者之间的区别:

1.调度:线程作为调度和分配的基本单位,进程是资源分配的基本。

2.并发性:不仅多个进程之间可以并发执行,同一进程多个线程之间也可以并发执行。

3.拥有资源:进程是拥有资源的一个独立单位,而线程不拥有系统资源,但可以访问隶属进程的资源

4.系统开销:在创建和撤销进程时,由于系统要为之分配和回收资源,导致系统的开销明显大于创建线程时的开销。

二.线程的生命周期(5种状态)

1.NEW(新建):即新建一个线程对象

2.RUNNABLE(就绪状态)线程对象创建后,其他线程比如(main线程)调用了该对象的start()方法,该线程就位于可运行线程池中,等待被线程调度选中,获取CPU的使用权。

3.RUNNING(运行状态)可运行状态获得了CPU时间片,执行程序代码。

4.BLOCKED(阻塞状态):阻塞状态是指线程遇到了某些问题而放弃了CPU的使用权。暂时停止运行,转换到就绪状态。才有机会再次获得CPU时间片。阻塞情况分三种:

  (1)等待阻塞:运行的线程执行o.wait()方法,JVM会把该线程放入等待序列中。

 (2)同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。

(3)其他阻塞:运行的线程执行Thread.sleep()或者t.join(),或者发出了I/O请求时,JVM会把该线程设为阻塞状态。

  5.DEAD(死亡状态)线程run()或者main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期,死亡的线程不可再次复生。


三.线程安全问题的原因归根是同一时刻有多个线程对共享资源进行操作而引起的,线程安全问题的解决办法是什么(两种),并简要介绍这两种方法?

答:(1)同步代码块

在对共享数据进行操作的代码块中加上synchronized(同步监视器,即锁){//需要被同步的代码,即对共享资源进行操作的代码块},这里的同步监视器可以是任何一个对象来充当,甚至直接Object obj = new Object();后用obj来充当,但是关于同步锁的声明也必须声明为共享资源,即不能在run()方法中声明,这里继承和实现又有所不同,继承的方法中对于同步锁的声明必须写成staticObject obj = new Object()的形式,但是实现的方式可以写成Object obj =new Object();更可以不用定义,直接用当前对象this来作为同步锁,但继承方式的线程不能用this;

(2)同步方法(只有实现方式线程可以用,继承方式的线程不可以用!)

同步方法就是在一个方法上加上锁,并且锁默认的是this,不能为其他,这也是为什么只能实现方式的线程类可以用,而继承方式的线程类不能用,这里通常是把对共享资源的操作单独拿出来封装在一个方法中,然后对这个方法加锁同步。

.四.sleep()和wait()的区别:

1.sleep()是Thread类的方法,wait()是Object类的方法

2.wait()只能用在同步块中,而sleep()是可以用在各个地方。

3.sleep()必须指定具体的时间,而wait()不需要。

4.sleep()不释放锁,而wait()需要释放锁

5.sleep()时间到了会自动结束睡眠,wait()必须要对其进行唤醒。

五.sleep()和yield()的区别:

1.sleep()方法会给其他线程运行的机会,不考虑其他线程的优先级,因此会给较低优先级线程一个机会,yield()方法只会给相同优先级或者更高优先级的线程一个运行的机会。

2.当线程执行了sleep()方法后,将转到阻塞状态,当执行了yield()方法会转到就绪状态。

3.sleep()方法声明抛出InterruptedException异常,而yield()方法没有声明抛出任何异常。

猜你喜欢

转载自blog.csdn.net/qq_42383970/article/details/80747189