Java面试之多线程&并发篇

打印 上一主题 下一主题

主题 889|帖子 889|积分 2667

前言

本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!如何停止一个正在运行的线程?notify()和notifyAll()有什么区别?sleep()和wait() 有什么区别?volatile 是什么?可以保证有序性吗?似乎有点含糊了,那就大概看一下面试题吧。好记性不如烂键盘
*** 12万字的java面试题整理 ***
如何停止一个正在运行的线程


  • 使用退出标记,使线程正常退出,也就是当run方法完成后线程停止。
  • 使用stop方法强行停止,但是不保举这个方法,因为stop和suspend及resume一样都是逾期作废的方法。
  • 使用interrupt方法停止线程。
  1. class MyThread extends Thread {
  2.    volatile boolean stop = false;
  3.     public void run() {
  4.          while (!stop) {
  5.                 System.out.println(getName() + " is running");
  6.                 try {
  7.                     sleep(1000);
  8.                 } catch (InterruptedException e) {
  9.                     System.out.println("week up from blcok...");
  10.                     stop = true; // 在异常处理代码中修改共享变量的状态
  11.               }
  12.          }
  13.         System.out.println(getName() + " is exiting...");
  14.   }
  15. }
  16. class InterruptThreadDemo3 {
  17.           public static void main(String[] args) throws InterruptedException {
  18.                     MyThread m1 = new MyThread();
  19.                     System.out.println("Starting thread...");
  20.                     m1.start();
  21.                     Thread.sleep(3000);
  22.                     System.out.println("Interrupt thread...: " + m1.getName());
  23.                     m1.stop = true; // 设置共享变量为true
  24.                     m1.interrupt(); // 阻塞时退出阻塞状态
  25.                     Thread.sleep(3000); // 主线程休眠3秒以便观察线程m1的中断情况
  26.                     System.out.println("Stopping application...");
  27.       }
  28. }
复制代码
notify()和notifyAll()有什么区别?

notify可能会导致死锁,而notifyAll则不会
任何时间只有一个线程可以获得锁,也就是说只有一个线程可以运行synchronized 中的代码
使用notifyall,可以唤醒 所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个。
wait() 应共同while循环使用,不应使用if,务必在wait()调用前后都检查条件,如果不满足,必须调用notify()唤醒别的的线程来处理,自己继续wait()直至条件满足再往下实行。
notify() 是对notifyAll()的一个优化,但它有很精确的应用场景,并且要求精确使用。否则可能导致死锁。精确的场景应该是 WaitSet中等待的是雷同的条件,唤醒任一个都能精确处理接下来的事项,如果唤醒的线程无法精确处理,务必确保继续notify()下一个线程,并且自身需要重新回到WaitSet中.
sleep()和wait() 有什么区别?

对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。
sleep()方法导致了步伐暂停实行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。
当调用wait()方法的时间,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备,获取对象锁进入运行状态。
volatile 是什么?可以保证有序性吗?

一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了差异线程对这个变量进行操纵时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的,volatile关键字会逼迫将修改的值立即写入主存。
2)克制进行指令重排序。
volatile 不是原子性操纵
什么叫保证部分有序性?
当步伐实行到volatile变量的读操纵或者写操纵时,在其前面的操纵的更改肯定全部已经进行,且效果已经对后面的操纵可见;在厥后面的操纵肯定还没有进行;
  1. x = 2; //语句1
  2. y = 0; //语句2
  3. flag = true; //语句3
  4. x = 4; //语句4y = -1; //语句5
复制代码
由于flag变量为volatile变量,那么在进行指令重排序的过程的时间,不会将语句3放到语句1、语句2前面,也不会讲语句3放到语句4、语句5后面。但是要注意语句1和语句2的次序、语句4和语句5的次序是不作任何保证的。
使用volatile 一般用于 状态标记量 和 单例模式的双检锁。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

缠丝猫

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表