面试题

java面试之四

2017-08-07  本文已影响12人  lijiaccy
1、你常用的jvm监控工具或者命令有哪些
2、java8的lambda表达式了解过吗?

java8之前:

new Thread(new Runnable(){
     public void run() {
         System.out.println(1123);
     }
}).start();

java8:

    new Thread(() -> System.out.println(123)).start();

还有其他的好多东西,下次找个时间专门研究一下这个。

3、A,B两个线程同时启动,但让A结束后B在结束,如何实现。

用join关键字。t.join()方法阻塞调用此方法的线程(calling thread),直到线程t完成,此线程再继续;通常用于在main()主线程内,等待其它线程完成再结束main()主线程。例如:

public class Test implements Runnable{

private String name;

public Test(String name) {
    this.name = name;
}

@Override
public void run() {
    try {
        Thread.sleep(1000);
    System.out.println(new Date()+"  "+name);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(new Test("zhangsan"));
    Thread thread1 = new Thread(new Test("lijia"));
    thread.start();
    thread1.start();
    thread.join();
    thread1.join();
    System.out.println("qqqqqqqqqqqq");
}
}
运行结果

如果把join去掉:

Paste_Image.png
4、java中什么是锁

我认为面试官一般问这种问题都是想问你synchronized。主要是问完这个也会顺带着问Lock。锁里面还有一些概念公平锁、非公平锁、自旋锁、可重入锁、偏向锁、轻量级锁、重量级锁、读写锁、互斥锁等。
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:

运行结果为


加上synchronized之后

再没有加锁之前,两个线程相互调用cpu,加锁之后,SyncThread1线程执行完才到SyncThread2,而且保证了正确性。

那么再说说volatile吧

还是用上面的例子说明,其他都不动

 private volatile int count;//在count这加入volatile

运行结果

图片.png 图片.png

用volatile只能保证可见性,但是不保证原子性。如上图,结果就是不正确的。
volatile也能禁止重排序

那么volatile怎么保证可见性和禁止重排序
引入深入理解java虚拟机中一段话: 观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令
lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:
1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
2)它会强制将对缓存的修改操作立即写入主存;
3)如果是写操作,它会导致其他CPU中对应的缓存行无效。
使用volatile必须具备以下2个条件:
1)对变量的写操作不依赖于当前值
2)该变量没有包含在具有其他变量的不变式中
也会说道Lock和AQS,请看
http://www.jianshu.com/p/d333d5177498
也许会问JUC下的一些其他类,这里不说了。

上一篇下一篇

猜你喜欢

热点阅读