备战2022春招-java-day3

java

  1. java锁

    • 公平锁:是指多个线程按照申请锁的顺序来获取锁,类似排队打饭,先来后到
    • 非公平锁:是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁在高并发的情况下,有可能会造成优先级反转或者饥饿现象
    • 可重入锁(递归锁):指的是同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁,即,线程可以进入任何一个它已经拥有的锁所同步着的代码块(避免死锁)
    • 自旋锁:指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少上下文切换的消耗,缺点是循环会消耗CPU
    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
    
        return var5;
    }
    
    • 独占锁(写锁):指该锁一次只能被一个线程所持有。对ReentrantLock和synchronized而言都是独占锁。
    • 共享锁(读锁):指该锁可被多个线程所持有。对ReentrantReadWriteLock其读锁是共享锁,其写锁是独占锁。读锁的共享锁可保证并发读是非常高效的,读写,写读,写写的过程是互斥的。
      • 写操作:原子+独占,整个过程必须是一个完整的统一体,中间不许被分割,被打断。
  2. (同步工具类) CountDownLatch:锁存器

    • countDown()方法:递减锁存器的计数
    • await()方法:使当前线程在锁存器倒计时至零之前一直等待,除非线程中断
    public class CountDownLatchDemo {
        public static void main(String[] args) throws InterruptedException {
            CountDownLatch countDownLatch = new CountDownLatch(6);
    
            for (int i = 1; i <= 6; i++) {
                new Thread(() -> {
                    System.out.println(Thread.currentThread().getName() + "\t上完自习,走出教室");
                    countDownLatch.countDown();
                }, String.valueOf(i)).start();
            }
    
            countDownLatch.await();
            System.out.println(Thread.currentThread().getName() + "\t教室里已没人");
    
        }
    }
    
  3. (同步工具类)CyclicBarrier:循环栅栏

    • 作用:让所有线程都等待完成后才会继续下一步行动。场景:集齐7颗龙珠召唤神龙
    • 常用构造函数
    // 第一个参数:线程数量
    // 第二个参数:线程,当所有线程执行完成后才做的动作
    public CyclicBarrier(int parties, Runnable barrierAction) {
        if (parties <= 0) throw new IllegalArgumentException();
        this.parties = parties;
        this.count = parties;
        this.barrierCommand = barrierAction;
    }
    
    • await()方法:阻塞线程
    public class CyclicBarrierDemo {
        public static void main(String[] args) {
            CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
                System.out.println(Thread.currentThread().getName() + "\t#######\t召唤神龙成功");
            });
    
            for (int i = 1; i <= 7; i++) {
                final int tempInt = i;
                new Thread(() -> {
                    System.out.println(Thread.currentThread().getName() + "\t集齐第" + tempInt + "颗龙珠");
                    try {
                        cyclicBarrier.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }, String.valueOf(i)).start();
            }
        }
    }
    

    运行结果:
    在这里插入图片描述

  4. Semaphore(信号量)

    • 主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制
    • 场景:争车位
    public class SemaphoreDemo {
        public static void main(String[] args) {
            Semaphore semaphore = new Semaphore(3);// 模拟3个车位
    
            for (int i = 1; i <= 6; i++) {
                new Thread(() -> {
                    try {
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName() + "\t抢到车位");
                        TimeUnit.SECONDS.sleep(3);
                        System.out.println(Thread.currentThread().getName() + "\t停车3秒后离开车位");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        semaphore.release();
                    }
                }, String.valueOf(i)).start();
            }
        }
    }
    

    在这里插入图片描述

算法

  • 有序数组的平方
    给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
    示例 1:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/squares-of-a-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一:暴力排序。每个数平方之后,然后排序

class Solution {
    public int[] sortedSquares(int[] nums) {
        int left = 0, right = nums.length-1;
        while (left <= right) {
            nums[left] = nums[left] * nums[left];
            left++;
        }
        Arrays.sort(nums);
        return nums;
    }
}

解法二:双指针法-----数组其实是有序的,只不过负数平方之后可能成为最大数了。那么数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。具体,i指向最左边,j指向最右边。
定义一个新数组result,和原数组一样大小,让k指向result数组终止位置。
如果A[i] * A[i] < A[j] * A[j] 那么result[k–] = A[j] * A[j];

如果A[i] * A[i] >= A[j] * A[j] 那么result[k–] = A[i] * A[i];

class Solution {
    public int[] sortedSquares(int[] nums) {
        int left = 0, right = nums.length - 1;
        int[] result = new int[nums.length];
        int index = result.length-1;
        while (left <= right) {
            if (nums[left] * nums[left] < nums[right] * nums[right]) {
                result[index--] = nums[right] * nums[right];
                right--;
            } else {
                result[index--] = nums[left] * nums[left];
                left++;
            }
        }
        return result;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值