美文网首页
JAVA面试

JAVA面试

作者: 徐振杰 | 来源:发表于2019-04-15 00:02 被阅读0次

volatile:

  1. 保证可见性
  2. 不保证原子性
  3. 禁止指令重排序

为什么不保证原子性?
因为当一个两个线程一起写入工作内存的时候,一个线程挂起,一个线程写入,当写入的线程通知的时候,另一个线程还没有来的及收到通知,就写入工作内存中,所以就没有原子性了

单例模式要加volatile来禁止指令重排
可以用AtomicInteger来替代

AtomicInteger的底层是CAS

JMM:

  1. 可见性
  2. 原子性
  3. 有序性

CAS:

  1. unsafe :是CPU的一条并发原语,用内存地址偏移量来修改值,直到比较成功才更新成功
  2. 自旋锁
    缺点:
  3. 会一直自旋,循环开销大,给cpu导致很大的开销
  4. 只能对一个共享变量进行原子性操作
  5. ABA问题:用修改版本号来避免AtomicStampedReference

ArrayList:
线程不安全,解决:

  1. vector 加了synchronize的ArrayList
  2. Collections.synchronizedList(new ArrayList<>());
  3. new CopyOnWriteArrayList<>();用了volatile和写时复制
    CopyOnWriteArraySet用的也是CopyOnWriteArrayList
    原因:一个同学在修改的时候,另一个同学过来修改,导致并发异常

HashSet底层是HashMap
他的value是present的一个Object类

ConcurrentHashMap只会对一段数据上锁,而不会对整个map上锁

公平锁和非公平锁
synchronize是非公平锁
ReentrantLock可以选择,默认是非公平锁

这两个锁都是可重入锁,可以避免死锁

自旋就是while循环加CAS,但是如果自旋锁太重了,可能会拖慢系统,因为等待的线程一直在自旋。

public class Main {

    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    public void myLock(){
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+" is  comming");
        while(!atomicReference.compareAndSet(null, thread)){}
    }
    public void unLock(){
        Thread thread = Thread.currentThread();
        atomicReference.compareAndSet(thread, null);
        System.out.println(Thread.currentThread().getName()+"It's time to unlock");
    }
    public static void main(String[] args) {

        Main main = new Main();

        new Thread(()->{
            main.myLock();
            try{
                TimeUnit.SECONDS.sleep(5);
            }catch(Exception e){
                e.printStackTrace();
            }
            main.unLock();
        }).start();

        try{
            TimeUnit.SECONDS.sleep(1);
        }catch(Exception e){
            e.printStackTrace();
        }

        new Thread(()->{
            main.myLock();
            try{
                TimeUnit.SECONDS.sleep(1);
            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println("------------------");
            main.unLock();
        }).start();
        
    }
}

相关文章

网友评论

      本文标题:JAVA面试

      本文链接:https://www.haomeiwen.com/subject/qipewqtx.html