线程 java面试

1.进程和线程的区别是什么?

  • 进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。 线程又叫做轻量级进程。

2.创建线程有几种不同的方式?

有三种方式可以用来创建线程:

  • 继承 Thread 类
  • 实现 Runnable 接口
  • 应用程序可以使用 Executor 框架来创建线程池
  • 实现 Runnable 接口这种方式更受欢迎,因为这不需要继承 Thread 类。在应用设计中已经继 承了别的对象的情况下,这需要多继承(而 Java 不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。*接口可以继承多个,而且接口实现的是功能,实例化对象时不用构造特定的类,这样更加灵活,易用性更好。可以处理同一资源,从而实现资源的共享.(后面的解释更好一点。)

3.概括的解释下线程的几种可用状态。

  1. 新建( new ):新创建了一个线程对象。

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

  3. 运行( running ):可运行状态( runnable )的线程获得了cpu时间片( timeslice ),执行程序代码。

  4. 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu时间片 timeslice ,暂时停止运行。直到线程进入可运行( runnable )状态,才有 机会再次获得 cpu timeslice 转到运行( running )状态。阻塞的情况分三种:
    (一). 等待阻塞:运行( running )的线程执行 wait ()方法, JVM 会把该线程放入等待队列( waitting queue )中。
    (二). 同步阻塞:运行( running )的线程在获取对象的同步锁时,若该同步锁 被别的线程占 用,则 JVM 会把该线程放入锁池( lock pool )中。
    (三). 其他阻塞: 运行( running )的线程执行sleep()或 join ()方法,或者发出了 I / O 请求时, JVM会把该线程置为阻塞状态。 当sleep()状态超时、 join()等待线程终止或者超时、或者 I / O 处理完毕时,线程重新转入可运行( runnable )状 态。

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

     举例:
     早上打车去上班 新建(准备叫一辆嘀嘀打车)
     可运行(找到一辆可以带你去上班的车)
     运行(司机接到你,带你去上班)
     阻塞(路上堵车了) 
     死亡(到公司了,付钱下车)
    

4.同步方法和同步代码块的区别是什么?

  • 同步方法默认用 this 或者当前类 class 对象作为锁,无法选择以什么来加锁;

  • 同步代码块可以选择以什么来加锁,比同步方法要更细颗粒度,我们可以选择只同步会发 生同步问题的部分代码而不是整个方法;

    5.什么是死锁(deadlock)?

  • 两个线程或两个以上线程都在等待对方执行完毕才能继续往下执行的时候就发生了死锁。结果就是这些线程都陷入了无限的等待中。

    6.如何确保 N 个线程可以访问 N 个资源同时又不导致死锁?

  • 使用多线程的时候,一种非常简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定的顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。

    7.sleep() 和 wait() 的区别

  • sleep 就是正在执行的线程主动让出 cpu,cpu 去执行其他线程,在 sleep 指定的时间 过后,cpu 才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep 方法并不会释放锁,即使当前线程使用 sleep 方法让出了 cpu,但其他被同步锁挡住 了的线程也无法得到执行。

  • wait 是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线 程调用了 notify 方法(notify 并不释放锁,只是告诉调用过 wait 方法的线程可以去 参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。 如果 notify 方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在 notfiy 方法后增加一个等待和一些代码,看看效果),调用 wait 方法的线程就会解除 wait 状态和程序可以再次得到锁后继续向下运行。

    8.实现同步的方式

同步是多线程中的重要概念。同步的使用可以保证在多线程运行的环境中,程序不会产生设 计之外的错误结果。同步的实现方式有两种,同步方法和同步块,这两种方式都要用到 synchronized 关键字。
1.同步方法
即有 synchronized 关键字修饰的方法。 由于 java 的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。 (对象锁)
代码如:

public synchronized void save(){} 

注: synchronized 关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类 (类锁)

public static synchronized void save(){} 

2.同步代码块
即有 synchronized 关键字修饰的语句块。 被该关键字修饰的语句块会自动被加上内置锁,从而实现同步
代码如:

synchronized(object){ } //这种最高效,推荐使用

注:同步是一种高开销的操作,因此应该尽量减少同步的内容。 通常没有必要同步整个方法,使用 synchronized 代码块同步关键代码即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值