尚硅谷互联网面试题第二季

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//原子性
public class VolatileDemo {
    public static void main(String[] args) {
        Mydata mydata = new Mydata();
       new Thread(()->{
            System.out.println(Thread.currentThread().getName() + "1");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mydata.addT060();
            System.out.println(Thread.currentThread().getName() + "update");

        },"A").start();
        while (mydata.num == 0){
        }
        System.out.println(Thread.currentThread().getName() + "2");
    }
}

class Mydata{
    volatile int num = 0;
    public void addT060(){
        this.num = 60;
    }
}

//A1
//Aupdate
//线程一直运行

验证不能保证原子性


在这里插入图片描述

在putfield时,其他线程挂起,没有及时得到主内存的值改变消息

public class VolatileDemo {

    private static ExecutorService executorService = Executors.newFixedThreadPool(20);

    // 验证可见性
    /*public static void main(String[] args) {
        Mydata mydata = new Mydata();
       new Thread(()->{
            System.out.println(Thread.currentThread().getName() + "1");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mydata.addT060();
            System.out.println(Thread.currentThread().getName() + "update");

        },"A").start();
        while (mydata.num == 0){
        }
        System.out.println(Thread.currentThread().getName() + "2");
    }*/
    // 验证不能保证原子性(已经volatile修饰了)
    public static void main(String[] args) {
        Mydata mydata = new Mydata();
        for (int i = 1; i <= 20; i++) {

            new Thread(()->{
                for (int j = 1; j <= 1000; j++) {
                    mydata.addPlus();
                    mydata.addPlusByAtomic();
                }
            }, String.valueOf(i)).start();
        }

        //暂停一会儿线程
        //需要等待上面20个线程全部计算完成后,由main方法取出结果值
      /*  try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }*/

        //必定有2个线程 main和gc
        while (Thread.activeCount() > 2){
            //礼让线程,本线程不执行
            Thread.yield();
        }

        System.out.println("finally print:" + mydata.num);
        System.out.println("finally print by atomic:" + mydata.atomicInteger);
    }
}


class Mydata{
    volatile int num = 0;

    public void addT060(){
        this.num = 60;
    }

    //
    public void addPlus(){
        num++;
    }

    AtomicInteger atomicInteger = new AtomicInteger(0);
    public void addPlusByAtomic(){
        atomicInteger.getAndIncrement();
    }

}

有序性

在这里插入图片描述

指令重排序在这里插入图片描述

在这里插入图片描述

不能,存在数据的依赖性

在这里插入图片描述
在这里插入图片描述

存在一种情况,那就是先执行的flag=true a=1还未执行,这是其他线程抢占到资源,执行method2,最后结果为5 ,此时加入volatile关键字,禁止指令重排序即可解决问题

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

volatile的使用场景

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CAS

如果线程的期望值和物理内存的真实值一样,则修改更新值,如果不一样,本次修改失败,重新获取主物理内存的值。

在这里插入图片描述
**加粗样式**
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

this:当前这个对象 valueoffset:内存偏移量(这个对象的地址值),
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

CAS缺点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
搞清楚变量的作用域
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

同步方法访问里层的同步方法,用的是同一把锁

case one

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

case two

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

lock可以重复,但是需要配对,有申请就需要就释放

自旋锁
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
自旋锁:优点:不会阻塞,缺点,一直循环,系统变慢

在这里插入图片描述

独占锁(写锁)/共享锁(读锁)/互斥锁

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public class Lock8Demo1 {

    public static void main(String[] args) {
        Phone phone = new Phone();
        new Thread(()->{
            try {
                phone.sendEmail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"A").start();

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            try {
                phone.sendMsg();
            } catch (Exception e) {
                e.printStackTrace();
            }
        },"B").start();
    }
}

class Phone{
    public synchronized void sendMsg() throws Exception{
        TimeUnit.SECONDS.sleep(4);
        System.out.println("sendMsg**************");
    }
    public synchronized void sendEmail() throws Exception{
        System.out.println("sendEmail**************");
    }
public void sayHello(){
        System.out.println("sayHello**************");
    }

生产者消费者

在这里插入图片描述


/**
 * @author:
 * @description:
 * @create: 2019-11-03 12:03
 * 使用synchronized系列完成
 * 题:现在两个线程,现在操作初始值为零的变量,实现一个线程对该变量加一,一个线程对该变量减一,操作10轮
 * 多线程交互关键:
 * 1.高内聚低耦合前提下,线程操作资源类
 * 2.判断,干活,通知
 * 3.防止虚假唤醒(多线程交互种判断必须要用while,不能用if)
 */
public class ProdecureConsumerDemo {
    public static void main(String[] args) {
        //资源类
        Aircondition ad = new Aircondition();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                ad.increment();
            }
        },"A").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                ad.decrement();
            }
        },"B").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                ad.increment();
            }
        },"C").start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                ad.decrement();
            }
        },"D").start();
    }
}

class Aircondition{
    private int num = 0;
    public synchronized void increment(){
        // 判断
       // if (num != 0){
        while (num != 0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 干活
        num++;
        System.out.println(Thread.currentThread().getName() + ":" + num);
        // 通知
        this.notifyAll();
    }

    public synchronized void decrement(){
        //if (num == 0){
            while (num == 0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 干活
        num--;
        System.out.println(Thread.currentThread().getName() + ":" + num);
        // 通知
        this.notifyAll();
    }
}



在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public class CountDownLatchDemo {

    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(6);

        for (int i = 0; i < 6; i++) {
             new Thread(() -> {
                 System.out.println(Thread.currentThread().getName()+ "离开了教室");
                countDownLatch.countDown();
              }, String.valueOf(i)).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "最后一个人离开了教室");
    }
    
    
}

CyclicBarrier

 public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
            System.out.println("第七次了,我执行了");
        });

        for (int i = 0; i < 7; i++) {
            final int temp = i;
            new Thread( ()->{
                System.out.println(temp);
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(i)).start();
        }
    }

Semaphore

public class SemaphoreDemo {

    public static void main(String[] args) {
        // 模拟资源类,当前有3个车位
        Semaphore semaphore = new Semaphore(3);

        for (int i = 0; i < 6; i++) {

            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "\t抢到了车位");

                    TimeUnit.SECONDS.sleep(1);
                    System.out.println(Thread.currentThread().getName() + "\t离开了车位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }

            }, String.valueOf(i)).start();

        }

    }
}

在这里插入图片描述
在这里插入图片描述

读写锁

public class ReadWriteLockDemo {

    public static void main(String[] args) {

        MyCache myCache = new MyCache();

        for (int i = 0; i < 5; i++) {
            // lambda中不允许变量
            final int temp = i;
            new Thread(()->{
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                myCache.put(temp + "", temp + "");
            } ,String.valueOf(i)).start();
        }

        for (int i = 0; i < 5; i++) {
            // lambda中不允许变量
            final int temp = i;
            new Thread(()->{
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                myCache.get(temp + "");
            } ,String.valueOf(i)).start();
        }
    }

}


class MyCache{

    private Map<String, Object> map = new HashMap<>();
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    public void put(String key, Object value){
        readWriteLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + " \t 写入数据" + key);

            map.put(key, value);

            System.out.println(Thread.currentThread().getName() + " \t 写入完成");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }


    public void get(String key){
        readWriteLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + " \t 开始读取数据" );
            Object o = map.get(key);
            System.out.println(Thread.currentThread().getName() + " \t 读取完成" + key +":"+ o );
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock();
        }

    }


队列

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值