网络安全最新JUC常见类以及线程安全的集合类(2),从三流网络安全外包到秒杀阿里P7

一、网安学习成长路线图

网安所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、网安视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述

三、精品网安学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
在这里插入图片描述

四、网络安全源码合集+工具包

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

五、网络安全面试题

最后就是大家最关心的网络安全面试题板块
在这里插入图片描述在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

2.3多线程环境使用哈希表

2.3.1Hashtable

2.3.2ConcurrentHashMap


1.JUC常见类

============

JUC的全称:java.util.concurrent(concurrent指的是多线程相关操作)

1.1Callable接口


①Callable是什么:

Callable 是一个 interface . 相当于把线程封装了一个 “返回值”. 方便程序猿借助多线程的方式计算结果.

②为什么Callable接口更适合写这种关于计算的代码?

我们就是为了解决Runnable不方便返回结果这个问题

③我们使用Callable接口来解决这个问题的代码:

a.创建一个匿名内部类 , 实现 Callable 接口, 泛型参数表示返回值的类型。

b.重写 Callable 的 call 方法 , 实现1+2+3+…+1000的执行过程。

c.把 callable 实例使用 FutureTask 包装一下。

b.创建线程 , 线程的构造方法传入 FutureTask , 此时新线程就会执行 FutureTask 内部的 Callable 的。

e.call 方法 , 完成计算,   计算结果就放到了 FutureTask 的 对象task中。

f.在主线程中调用 futureTask.get() 能够阻塞等待新线程计算完毕 。 并获取到 FutureTask 中的结果。

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.FutureTask;

public class demo2{

public static void main(String[] args) throws ExecutionException, InterruptedException {
    Callable<Integer>callable=new Callable() {
        @Override
        public Object call() throws Exception {
           int sum=0;
           for(int i=0;i<=1000;i++){
               sum+=i;
           }
           return sum;
        }
    };
    //为了让线程执行Callable中的任务,光使用构造方法是不够的,还需要使用一个辅助类
    FutureTask<Integer>task=new FutureTask<>(callable);
    //创建线程,来完成这里的工作
    Thread t=new Thread(task);
    t.start();
    int result = task.get();
    System.out.println(result);
}

}

④进一步理解Callable接口:

Callable 和 Runnable 相对, 都是描述一个 “任务”. Callable 描述的是带有返回值的任务,

Runnable 描述的是不带返回值的任务。Callable 通常需要搭配 FutureTask 来使用。 FutureTask 用来保存 Callable 的返回结果.。因为Callable 往往是在另一个线程中执行的, 啥时候执行完并不确定。FutureTask 就可以负责这个等待结果出来的工作。

举个生活中的例子来进一步说明:

当我们去一个餐馆进行吃饭,点单的时候会给我们一个小票,当我们刚拿到小票时显然商家正准备进行加工,而当加工完成将要反馈给我们的时候,他会进行叫号,以便确保是谁的单。而这种反馈叫号的操作很明显就是用上面我们提到的FutureTask等待接收结果的这个行为。

1.2ReentrantLock


①ReentrantLock是什么?

ReentrantLock也是一种可重入锁,和 synchronized很像,两者都是用来实现互斥效果, 保证线程安全的。

②基本用法:(它是把加锁解锁两个操作进行分开的操作)

lock():加锁,如果获取不到就一直死等到获取到为止的操作

trylock(超时时间):加锁,如果一段时间仍然获取不到锁,就放弃加锁

unlock():解锁

③ReentrantLock和Synchronized的区别:

a.ReentrantLock是在JVM外部实现的一个标准库的类(基于Java来实现的),而synchronized是在JVM内部实现的一个关键字(基于C++来实现的)

b.ReentrantLock是需要我们进行手动加锁解锁的,使用起来确实更加灵活,但是很多时候手动释放也会被我们忽视。synchronized不需要手动释放锁,出了相应的代码块后,锁即自动释放。

c.ReentrantLock在锁竞争失败的时候除了阻塞等待以外,可以尝试trylock()来获取到锁,如果失败了就直接返回,给我们留下了更多的余地。而synchronized如果竞争的时候失败就会阻塞等待。

d.ReentrantLock既可以是公平锁,也可以是非公平锁,我们只需要在它的参数位置进行指定(默认是非公平锁,true即是公平锁),而synchronized只是一个非公平锁。

e.ReentrantLock 搭配 Condition 类实现等待-唤醒, 可以更精确控制唤醒某个指定的线程。 synchronized 是通过 Object 的 wait / notify 实现等待-唤醒.。每次唤醒的是一 个随机等待的线程,相对而言功能是有限的。

但是在我们的日常工作开发中,synchronized 就够用啦

1.3信号量 Semaphore


①什么是信号量:

信号量, 用来表示 “可用资源的个数”。实质上是一个更广义的锁。(锁也被称为二元信号量)

②举一个通俗的例子来帮助你理解信号量:

自驾去某个地方,我们经常会遇到停车的问题, 可以把信号量想象成是停车场的展示牌: 当前有车位 20 个,表示有 20 个可用资源。 当有车开进去的时候, 就相当于减少(申请资源)了一个可用资源, 可用车位就 -1 (这个称为信号量的 P 操作) 当有车开出来的时候, 就相当于增加(释放资源)一个可用资源, 可用车位就 +1 (这个称为信号量的 V 操作)。 如果计数器的值已经为 0 了, 还尝试申请资源, 就会阻塞等待, 直到有其他线程释放资源。

Semaphore 的 PV 操作中的加减计数器操作都是原子的, 可以在多线程环境下直接使用。

import java.util.concurrent.Semaphore;

public class demo2{

public static void main(String[] args) throws InterruptedException {
    //表示提供了10个资源
    Semaphore s=new Semaphore(3);
    //资源申请
    s.acquire();
    System.out.println("申请资源啦");
    s.acquire();
    System.out.println("申请资源啦");
    s.acquire();
    System.out.println("申请资源啦");
    s.acquire();
    System.out.println("申请资源啦");
    //释放资源
  //  s.release(1);
}

}

如图所示,这个时候只有3个资源位,要是我申请了3个后没有释放继续申请,那么程序就会出现阻塞的情况,结果如下图:(也就说只会打印3次)

1.4CountDownLatch


①什么是CountDownLatch?

这用文字不怎么好理解,所以给大家举一个例子:

大家应该都玩过王者荣耀吧,我们都知道最终的胜利是退掉敌方水晶,所以当我们退掉一座塔是不够的,我们需要把最终的水晶退掉,才能够结束这一场对局。

②相关方法的说明:

countDown 给每个线程里面去调用,就表示到达终点了。(就相当于上面提到游戏中每推掉一座塔)

await是给等待线程去调用.当所有的任务都到达终点了, await 就从阻塞中返回,就表示任务完成。(就相当于推掉水晶)

③代码演示:(注意,要等所有调用完了,即水晶推完,await才会返回。也就才会打印gameover…那句话)

a.没有调用完

b.调用完:

import java.util.concurrent.CountDownLatch;

public class demo2{

public static void main(String[] args) throws InterruptedException {
    //在游戏里,包括水晶,我们需要推掉4个塔
    CountDownLatch c=new CountDownLatch(4);
   for(int i=0;i<4;i++){
       Thread t=new Thread(()->{
           try {
               Thread.sleep(3000);
               c.countDown();
               System.out.println(Thread.currentThread().getName()+"推掉了1座塔");
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       });
       t.start();
      // t.join();不加这个的时候,线程的调度是将是随机的
   }
   c.await();
    System.out.println("gameover!恭喜你获得胜利");
}

写在最后

在结束之际,我想重申的是,学习并非如攀登险峻高峰,而是如滴水穿石般的持久累积。尤其当我们步入工作岗位之后,持之以恒的学习变得愈发不易,如同在茫茫大海中独自划舟,稍有松懈便可能被巨浪吞噬。然而,对于我们程序员而言,学习是生存之本,是我们在激烈市场竞争中立于不败之地的关键。一旦停止学习,我们便如同逆水行舟,不进则退,终将被时代的洪流所淘汰。因此,不断汲取新知识,不仅是对自己的提升,更是对自己的一份珍贵投资。让我们不断磨砺自己,与时代共同进步,书写属于我们的辉煌篇章。

需要完整版PDF学习资源私我

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值