多线程实例练习题~

本篇文章主要是用来巩固多线程的简单应用,如果你已经学习了多线程的有关知识,想要巩固,那不妨拿下面几道题来考验一下自己吧!

案例1:电影院售票(难度指数:一颗星)

题目:一共有1000张电影票,可以在两个窗口领取,假设每次领取的时间为3000毫秒,要求:请用多线程模拟买票过程并打印剩余电影票数量

题目分析:1000张电影票为两个窗口(两个线程)的共享资源,领取的时间对应多线程中的sleep方法

package org.example.My_Thread_Practice;

import java.util.concurrent.locks.ReentrantLock;

public class Practice1 extends Thread {
    //电影票的个数
    static int count=0;
    //创建锁对象
    ReentrantLock lock=new ReentrantLock();
    public static void main(String[] args) {
        Practice1 practice1=new Practice1();
        //创建两个线程用来模拟两个窗口
        Thread thread1=new Thread(practice1);
        Thread thread2=new Thread(practice1);
        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread1.start();
        thread2.start();
    }

    @Override
    public void run() {
        while(true){
            lock.lock();
                if(count<1000){
                    try {
                        //每次领取的时间为3000毫秒
                        sleep(3000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }finally {
                        lock.unlock();
                    }
                    count++;
                    System.out.println("第"+count+"张电影票卖出了!"+"售票窗口为:"+Thread.currentThread().getName());
                }else{
                    break;
                }
            }
        }
    }

输出如下所示:(部分输出结果)

在这里插入图片描述

案例2:送礼物(难度指数:两颗星)

题目: 有1000份礼品,两人同时发送,当剩下的礼品小于10份的时候则不再送出,利用多线程模拟该过程并将线程的名字和礼物的剩余数量打印出来

题目分析:本题和第一题大同小异,区别在于多了一个判断,当礼品(共享资源)数剩下10份不再送出

package org.example.My_Thread_Practice;


public class Practice2 extends Thread {
    static int count=0;

    static Object lock=new Object();
    public static void main(String[] args) {
        Practice2 practice=new Practice2();
        Thread thread1=new Thread(practice);
        thread1.setName("张三");
        Thread thread2=new Thread(practice);
        thread2.setName("李四");
        thread1.start();
        thread2.start();
    }

    @Override
    public void run() {
                while(true){
                   synchronized (lock) {
                       count++;
                       if (count < 989) {
                           System.out.println("第" + count + "份礼物被" + Thread.currentThread().getName() + "送出!还剩" + (989 - count) + "份礼物!");
                       } else {
                           break;
                       }
                   }
                }
    }
}

输出如下所示:(部分输出结果)

在这里插入图片描述

案例3:找奇数(难度指数:两颗星)

题目: 同时开启两个线程,共同获取1-100之间的所有数字,要求:将输出所有的奇数

package org.example.My_Thread_Practice;


public class Practice3 extends Thread {
    static Object lock=new Object();
    public static void main(String[] args) {
      
        Practice3 practice3=new Practice3();
        Thread thread1=new Thread(practice3);
        Thread thread2=new Thread(practice3);
        thread1.setName("线程1");
        thread2.setName("线程2");
        thread1.start();
        thread2.start();

    }

    @Override
    public void run() {
        for(int i=1;i<=100;i++){
            synchronized (lock){
                if(i%2==1){
                    System.out.println(i);
                }
            }
        }
    }
}

输出如下所示:(部分输出结果)

在这里插入图片描述

案例4:抢红包(难度指数:三颗星)

题目:抢红包:假设100块分成三个红包,现在有5个人去抢,其中,红包是共享数据,5个人是5条线程,
打印输出结果如下:
XXX抢到了XXX元,
XXX抢到了XXX元,
XXX抢到了XXX元,
XXX没抢到,
XXX没抢到

题目分析:100元红包作为共享资源,被分成三个,供5个人去抢,既然只有5个红包,那么则说明,有两个人一定没有抢到,因此,我们首先需要确定红包的几个特殊值,必须且只有三个红包,那么就不能出现这100块钱被一个或者两个人抢了,必须三个人都有那么一点,因此红包的最大金额只能是99.98,剩下的0.02分别被两个人平分。红包的数量只有三个,那么当红包数量只剩一个时,就不需要生成随机数了,直接将当前的剩余金额全部给最后一个红包,并且为了尽可能的贴近现实,所以当红包生成的红包金额小于0.01时,我们直接将其修改为0.01

package main.java.My_Thread_Practice;
public class Practice4 extends Thread{
    //共享数据
    static double sum=100;//红包总金额为100元
    static int RedBag=3;//红包的个数为3个
    static final double MIN=0.01;//最小中奖金额

    public static void main(String[] args) {
        Practice4 practice=new Practice4();
        Thread thread1=new Thread(practice);
        Thread thread2=new Thread(practice);
        Thread thread3=new Thread(practice);
        Thread thread4=new Thread(practice);
        Thread thread5=new Thread(practice);
        //我们可通过Ctrl+Shift+Alt快速选中多行,再预留出多行,快速可编写多行代码
        //5个人同时去抢,也就是五条线程
        thread1.setName("张三");
        thread2.setName("李四");
        thread3.setName("王五");
        thread4.setName("小明");
        thread5.setName("小红");
        //启动线程
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();
    }

    @Override
    public void run() {
        synchronized (Practice4.class){
            //红包抢完了没?
            //抢完了,直接输出没红包了
            //没抢完,再进行随机数抢红包
            if(RedBag==0){
                System.out.println(Thread.currentThread().getName()+"没有抢到红包!");
            }else{
               double prize;//红包的金额
                if(RedBag==1){//如果剩余红包数为1个,那么直接将剩下的所有金额给最后一个红包
                    prize=sum;
                }else {//通过随机数去生成不同的红包金额
                    //Math.random()生成一个0-1之间的随机小数
                    double random = Math.random();
                    //确定随机数的范围---并将最终的金额保留小数点后两位
                    prize= Double.parseDouble(String.format("%.2f",random * (sum-(RedBag-1)*MIN)));
                    if(prize<MIN){//如果最终获取到的结果小于0.01,那么直接让其为最小金额0.01
                        prize= MIN;
                    
                    }
                }//更新余额
                sum=sum-prize;
                RedBag--;
                System.out.println(Thread.currentThread().getName()+"抢到了"+prize+"元!");
            }
        }
    }
}

输出如下所示:

在这里插入图片描述

案例5:抢红包(难度指数:四颗星)

题目: 有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为{10,5,20,50,100,200,500,800,2,80,300,700};创建两个抽奖箱(线程)
设置线程名称分别为“抽奖箱1",“抽奖箱2",随机从抽奖池中获取奖项元素并打印在控制台上,格式如下
每次抽出一个奖项就打印一个(随机)
抽奖箱1 又产生了一个 10 元大奖
抽奖箱1又产生了一个 100 元大奖
抽奖箱1 又产生了一个 200 元大奖
抽奖箱1 又产生了一个 800 元大奖
抽奖箱2 又产生了一个 700 元大奖

题目分析:我们必须保证奖池的唯一性,因此不能最好的方法就是奖池中的某个奖被抽走后,我们立即删除它,最开始我是写了一个方法通过Random获取奖池中的任意值,表示随机数,然后再将其删除,但是ArrayList是不能被修改的,而且那种方法也很麻烦,下面的这种方法更加简单

package main.java.My_Thread_Practice;

import java.util.ArrayList;
import java.util.Collections;

public class Practice5 extends Thread {
    ArrayList<Integer> arrayList;
    public Practice5(ArrayList<Integer> arrayList){
        this.arrayList=arrayList;
    }
    @Override
    public void run() {
        while (true){
            synchronized (Practice5.class){
                if(arrayList.size()==0){
                    break;
                }else{
                    //将集合中的元素随机排列
                    Collections.shuffle(arrayList);
                    //我们抽中的始终为集合中的第一个元素
                    int prize=arrayList.remove(0);
                    System.out.println(Thread.currentThread().getName()+"又产生了一个"+prize+"元大奖");
                }
            }
        }
    }
    public static void main(String[] args) {
        //将list通过有参构造传递,而不是定义在run方法中,这样能够确保我们无论创建多少条线程,始终操作的都是同一个list
        ArrayList<Integer> list=new ArrayList<>();
        Collections.addAll(list,10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300, 700);
        Practice5 practice = new Practice5(list);
        Thread thread1 = new Thread(practice);
        Thread thread2 = new Thread(practice);
        thread1.setName("抽奖箱1");
        thread2.setName("抽奖箱2");
        thread1.start();
        thread2.start();
    }
}

输出如下所示:

在这里插入图片描述

声明一点,由于我们的测试数据很少,因此想要达到我上述这种有抽奖箱1,也有抽奖箱2的效果,方法1:可以多运行几次,方法2,在同步代码块的外面增加sleep方法,注意不能写在同步方法块里面,原因是,如果你写在里面,那么即使线程休眠一段时间,其他线程也不能执行同步代码块呀,所以并没达到我们想要的让两个线程尽可能的均匀执行的效果

案例5:抢红包(进阶)(难度指数:四颗半星)

题目:在上一题基础上继续完成如下需求:

每次抽的过程中,不打印,抽完时一次性打印(随机)

在此次抽奖过程中,抽奖箱1总共产生了6个奖项。分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元

在此次抽奖过程中,抽奖箱2总共产生了6个奖项。分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元

题目分析:它要求最后一次性进行打印,那么就说明,我们需要根据线程分别将奖项存放,并且需要计算最大值和总和,这里我们可以使用Collections提供的max方法求出最大值,也可以使用和我一样的,将集合定义为TreeSet而不是ArrayList,我这样做的好处就是TreeSet它默认是根据元素的自然顺序排序的,它本身就是一个有序集合,因此我寻找最大值只需要调用last方法就可以求出,总金额的话,就需要我们去变量集合累计求和

package main.java.My_Thread_Practice;

import java.util.ArrayList;
import java.util.Collections;
import java.util.TreeSet;

public class Practice5 extends Thread {
    ArrayList<Integer> arrayList;
    //存放抽奖箱1产生的奖
    TreeSet<Integer> bag1;
    //存放抽奖箱2产生的奖
    TreeSet<Integer> bag2;
    //抽奖箱1的总金额
    int sum1=0;
    //抽奖箱2的总金额
    int sum2=0;
    public Practice5(ArrayList<Integer> arrayList,TreeSet<Integer> bag1,TreeSet<Integer> bag2){
        this.bag1=bag1;
        this.bag2=bag2;
        this.arrayList=arrayList;
    }
    @Override
    public void run() {
        while (true){
            synchronized (Practice5.class){
                if(arrayList.size()==0){//当奖池中的奖分配完毕后,我们直接将两个抽奖箱中的结果输出即可
                    if(Thread.currentThread().getName().equals("抽奖箱1")){
                        for (Integer i:bag1) {
                            sum1+=i;
                        }
                        System.out.println("在此次抽奖过程中,"+Thread.currentThread().getName()+"总共产生了"+bag1.size()+"个奖项,分别为"+bag1+"最高奖项为:"+bag1.last()+"元,总计额为"+sum1+"元");
                    }else {
                        if (Thread.currentThread().getName().equals("抽奖箱2")) {
                            for (Integer i : bag2) {
                                sum2 += i;
                            }
                            System.out.println("在此次抽奖过程中,"+Thread.currentThread().getName() + "总共产生了" + bag2.size() + "个奖项,分别为" + bag2 + "最高奖项为:" + bag2.last() + "元,总计额为" + sum2 + "元");
                        }
                    }
                    break;
                }else{
                    //将集合中的元素随机排列
                    Collections.shuffle(arrayList);
                    //我们抽中的始终为集合中的第一个元素
                    int prize=arrayList.remove(0);
                    if(Thread.currentThread().getName().equals("抽奖箱1")){
                        bag1.add(prize);
                    }else {
                        bag2.add(prize);
                    }
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) {
        //将list通过有参构造传递,而不是定义在run方法中,这样能够确保我们无论创建多少条线程,始终操作的都是同一个list
        ArrayList<Integer> list=new ArrayList<>();
        //抽奖箱和奖池一样都是使用有参构造的形式传递,为的就是确保我们始终操作的抽奖箱是同一个
        //由于我们最终还需要分别获得两个箱子中的最高奖项,因此我们可以直接使用TreeSet,将元素添加到集合中就能够直接排序的功能
        //通过last方法就可以获取TreeSet中的最大值
        // 抽奖箱1
        TreeSet<Integer> bag1 = new TreeSet<>();
        //抽奖箱2
        TreeSet<Integer> bag2 = new TreeSet<>();
        Collections.addAll(list,10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300, 700);
        Practice5 practice = new Practice5(list,bag1,bag2);
        Thread thread1 = new Thread(practice);
        Thread thread2 = new Thread(practice);
        thread1.setName("抽奖箱1");
        thread2.setName("抽奖箱2");
        thread1.start();
        thread2.start();
    }
}

输出如下所示:

在这里插入图片描述

案例5:抢红包(进阶)优化版—线程栈

上述只是要求两个抽奖箱,因此我们创建了两个TreeSet,那么要是有100个,甚至1000个抽奖箱,我们难道要创建这么多的抽奖箱吗?当然不是,因此下述的这种方法,更加灵活和简答的实现了上述功能

Java中的堆是唯一的,而栈并不是唯一的

在这里插入图片描述

package main.java.My_Thread_Practice;

import java.util.ArrayList;
import java.util.Collections;
import java.util.TreeSet;

public class Practice5 extends Thread {
    ArrayList<Integer> arrayList;
    public Practice5(ArrayList<Integer> arrayList){
        this.arrayList=arrayList;
    }
    @Override
    public void run() {
        //无论哪条线程抢占到CPU执行run方法都会创建它专属的抽奖箱
        TreeSet<Integer> boxList=new TreeSet<>();
        //每个抽奖箱都会创建它专属的总金额
        int sum=0;
        while (true){
            synchronized (Practice5.class) {
                if (arrayList.size() == 0){//当奖池中的奖分配完毕后,我们直接将两个抽奖箱中的结果输出即可
                    for (Integer i:boxList) {
                        sum+=i;
                    }
                    System.out.println("在此次抽奖过程中,"+Thread.currentThread().getName() + "总共产生了" + boxList.size() + "个奖项,分别为" + boxList + "最高奖项为:" + boxList.last() + "元,总计额为" + sum + "元");
                break;
            }else{
                    Collections.shuffle(arrayList);
                    int prize=arrayList.remove(0);
                    boxList.add(prize);
                }
            }
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    public static void main(String[] args) {
        //将list通过有参构造传递,而不是定义在run方法中,这样能够确保我们无论创建多少条线程,始终操作的都是同一个list
        ArrayList<Integer> list=new ArrayList<>();
        Collections.addAll(list,10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300, 700);
        Practice5 practice = new Practice5(list);
        Thread thread1 = new Thread(practice);
        Thread thread2 = new Thread(practice);
        thread1.setName("抽奖箱1");
        thread2.setName("抽奖箱2");
        thread1.start();
        thread2.start();
    }
}

输出如下所示:

在这里插入图片描述

案例5:抢红包(进阶)优化版—线程之间的比较(难度指数:五颗星)

题目:在次基础上,我们再一次升级难度,要求打印出

在此抽奖过程中,抽奖箱X中产生了最大奖项,该奖金额为X元

这里设计到了线程间的比较,由于我们是将12个奖项随机的分配到两个奖箱中,因此在前面我们求出了每个箱子中的最大奖项还不够,我们这次还要想办法比较两个奖箱中最大值中较大的一个,并将其输出

题目分析:此次需求在之前的基础上,增加了让我们求两个奖项中较大的一个,这就涉及到了线程间的比较,我们可以通过线程的实现方式中的第三种,它的call方法能够返回线程的比较结果,我们只需要在main方法中分别获取不同线程的返回结果,再输出最大的即可,也可以通过将各个线程中的最大值以及线程名称加入到hashMap中,最后遍历hashMap求出最大值

第一种方法:使用Callable接口

package main.java.My_Thread_Practice;


import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class MyCallable implements Callable<Integer> {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300, 700);
        MyCallable myCallable=new MyCallable(list);
        FutureTask<Integer> ft1=new FutureTask<>(myCallable);
        FutureTask<Integer> ft2=new FutureTask<>(myCallable);
        Thread thread1=new Thread(ft1);
        Thread thread2=new Thread(ft2);
        thread1.setName("抽奖箱1");
        thread2.setName("抽奖箱2");
        thread1.start();
        thread2.start();
        //表示线程1获取到的最大值--抽奖箱1获得的最大值
        Integer max1=ft1.get();
        //表示线程2获取到的最大值--抽奖箱2获得的最大值
        Integer max2=ft2.get();
        //输出两个抽奖箱最大值中较大的那个
        if(max1>max2){
            System.out.println("在此抽奖过程中,抽奖箱1中产生了最大奖项,该奖金额为"+max1);
        }else {
            System.out.println("在此抽奖过程中,抽奖箱2中产生了最大奖项,该奖金额为"+max2);
        }

    }
    public MyCallable (ArrayList<Integer> integers){
        this.arrayList=integers;
    }
    ArrayList<Integer> arrayList;

    @Override
    public Integer call() throws Exception {
        //每条线程都会创建它专属的抽奖箱
        TreeSet<Integer> boxList = new TreeSet<>();
        //每个抽奖箱都会创建它专属的总金额
        int sum = 0;
        while (true) {
            synchronized (Practice5.class) {
                if (arrayList.size() == 0) {//当奖池中的奖分配完毕后,我们直接将两个抽奖箱中的结果输出即可
                    for (Integer i : boxList) {
                        sum += i;
                    }
                    System.out.println("在此次抽奖过程中," + Thread.currentThread().getName() + "总共产生了" + boxList.size() + "个奖项,分别为" + boxList + "最高奖项为:" + boxList.last() + "元,总计额为" + sum + "元");
                    break;
                } else {
                    Collections.shuffle(arrayList);
                    int prize = arrayList.remove(0);
                    boxList.add(prize);
                }
            }
            Thread.sleep(100);
        }
        //将每个抽奖箱中的最大值返回
        return Collections.max(boxList);
    }
}

输出如下所示:
在这里插入图片描述

第二种方式:使用hashMap

将每个奖项中产生的最大值和对应的奖箱名字存放在hashmap中,最后通过遍历hashmap输出最大值,即为所有奖箱中的最大值

package main.java.My_Thread_Practice;

import java.util.*;

public class Practice6 extends Thread {
    ArrayList<Integer> arrayList;
    HashMap<String,Integer> hashMap=new HashMap<>();

    public Practice6(ArrayList<Integer> arrayList){
        this.arrayList=arrayList;
    }
    @Override
    public void run() {
        //无论哪条线程抢占到CPU执行run方法都会创建它专属的抽奖箱
        TreeSet<Integer> boxList=new TreeSet<>();
        //每个抽奖箱都会创建它专属的总金额
        int sum=0;
        while (true){
            synchronized (Practice5.class) {
                if (arrayList.size() == 0){//当奖池中的奖分配完毕后,我们直接将两个抽奖箱中的结果输出即可
                    for (Integer i:boxList) {
                        sum+=i;
                    }
                    System.out.println("在此次抽奖过程中,"+Thread.currentThread().getName() + "总共产生了" + boxList.size() + "个奖项,分别为" + boxList + "最高奖项为:" + boxList.last() + "元,总计额为" + sum + "元");
                    hashMap.put(Thread.currentThread().getName(),boxList.last());
                    break;
                }else{
                    Collections.shuffle(arrayList);
                    int prize=arrayList.remove(0);
                    boxList.add(prize);
                }
            }
        }
        Map.Entry<String, Integer> maxEntry = null;
        for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
            if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0) {
                maxEntry = entry;
            }
        }
            System.out.println("在此次抽奖过程中," + maxEntry.getKey() + "中产生了最大奖项,该奖项金额为:" + maxEntry.getValue()+"元");
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        //将list通过有参构造传递,而不是定义在run方法中,这样能够确保我们无论创建多少条线程,始终操作的都是同一个list
        ArrayList<Integer> list=new ArrayList<>();
        HashMap<String ,Integer> hashMap=new HashMap<>();
        Collections.addAll(list,10, 5, 20, 50, 100, 200, 500, 800, 2, 80, 300, 700);
        Practice6 practice = new Practice6(list);
        Thread thread1 = new Thread(practice);
        Thread thread2 = new Thread(practice);
        thread1.setName("抽奖箱1");
        thread2.setName("抽奖箱2");
        thread1.start();
        thread2.start();

    }
}

输出如下所示:

这种方式有个弊端就是最大奖项哪条输出语句输出的次数为线程的个数

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/340141.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

8.3 Springboot整合Redis 之Jedis方式

文章目录 前言一、Maven依赖二、新增子Module:tg-book-redis三、Jedis配置类3.1 Jedis连接池核心配置说明四、Jedis 工具类五、新增controller测试前言 Jedis是Redis官方推荐的Java客户端连接工具,用法非常简单,Jedis的API与Redis的API可以说是一模一样,所以非常有利于熟悉…

深入掌握 OSS,最完美的 OSS 上传方案!

文件上传是常见需求&#xff0c;一般我们不会把文件直接上传到应用服务器&#xff0c;因为单台服务器存储空间是有限的&#xff0c;不好扩展。 我们会用单独的 OSS &#xff08;Object Storage Service&#xff09;对象存储服务来上传下载文件。 比如一般会买阿里云的 OSS 服…

M1 MacOS下安卓虚拟化的最佳方案

categories: [VM] tags: MacOS VM 写在前面 一直想在桌面环境虚拟化安卓app, 但是看网上的推荐一直感觉不合胃口, 不是要花钱就是有广告, 想着找找开源的实现, 后来发现还是 Google 自家的产品用着舒服. 安装与配置 brew install android-studio然后随便开一个项目, 选默认…

【window】Windows11:该文件没有与之关联的应用来执行该操作

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能 之前win10升级win11后&#xff0c;受不了桌面软件图标的的小箭头&#xff0c;所以弄掉了&#xff0c;但是随之而来产…

python实现带刷新的文本进度条

进度条已执行的部分使用“**”&#xff0c;未执行的部分使用“--”&#xff0c;用print&#xff08;&#xff09;来完成 使用到的函数&#xff1a; time.sleep(),作用是在程序执行过程中暂停一段时间&#xff0c;即会使程序暂停指定的秒数&#xff0c;然后再继续执行后面的代…

c/c++的指针函数与函数指针

函数 定义&#xff1a; 函数是数学中的一个概念&#xff0c;它是定义在某个数集上的一个特殊的映射关系。函数将输入值&#xff08;或自变量&#xff09;映射到输出值&#xff08;或因变量&#xff09;。函数的输入和输出可以是任何类型的数据&#xff0c;如数字、字符串、数组…

伪原创文章生成器软件免费使用的方法

写文章不仅消耗时间&#xff0c;而且还容易出现写不出内容的问题&#xff0c;随着技术的发展&#xff0c;越来越多的人开始不再亲历亲为的去写文章了&#xff0c;而是用起了伪原创文章生成器软件&#xff0c;对于还不了解自动生成文章软件的人&#xff0c;可不要小瞧这个它了&a…

世微 AP5199S 降压恒流IC 车灯景观灯舞台灯 过EMC认证线路图

说明 AP5199S 是一款电路简单的多功能平均电流 型 LED 恒流驱动器&#xff0c;适用于宽电压范围的非隔离式 大功率恒流 LED 驱动领域。 芯片 PWM 端口支持超小占空比的 PWM 调光&#xff0c; 可响应 60ns 脉宽。芯片采用我司算法&#xff0c;为客 户提供解决方案&#xff0c;限…

MarkDown学习笔记 直观全面详细

前言 为什么我们要学习Markdown呢&#xff1f;因为Markdown简单易学易上手&#xff0c;可以以纯文本格式编写文档&#xff0c;然后转换成有效的HTML文档&#xff0c;并且以导出 HTML 、Word、图像、PDF、Epub 等多种格式的文档&#xff0c;许多网站平台的文章、博客、论文均可…

【Java并发】聊聊活锁

在并发编程中&#xff0c;为了保证数据安全性&#xff0c;所以使用锁机制&#xff0c;syn lock cas 等方式保证&#xff0c;但是也从一定程度降低了性能。而除了这个方面&#xff0c;还引入了锁竞争&#xff0c;比如死锁、活锁。 【Java并发】聊聊死锁 避免死锁&#xff1a;避…

vue项目编译非常慢,经常卡在某个百分点

1、注册插件 2、在项目根目录下的 babel.config.js 文件中加入下方配置 3、将import导入方式改为require导入方式&#xff0c;返回promise 4、如果动态加载组件import引入组件找不到组件&#xff08;Error: Cannot find module&#xff09; 使用 webpack 的 require.ensure() …

Kafka-服务端-DelayedOperationPurgatory

DelayedOperationPurgatory是一个相对独立的组件&#xff0c;它的主要功能是管理延迟操作。 DelayedOperationPurgatory的底层依赖于Kafka提供的时间轮实现。 我们可以使用JDK本身提供的java.util.Timer或是DelayQueue轻松实现定时任务的功能&#xff0c;为什么Kafka还要专门…

C++11手撕线程池 call_once 单例模式 Singleton / condition_variable 与其使用场景

一、call_once 单例模式 Singleton 大家可以先看这篇文章&#xff1a;https://zh.cppreference.com/w/cpp/thread/call_once /*std::call_oncevoid call_once( std::once_flag& flag, Callable&& f, Args&&... args ); */ #include <iostream> #i…

Flash读取数据库中的数据

Flash读取数据库中的数据 要读取数据库的记录&#xff0c;首先需要建立一个数据库&#xff0c;并输入一些数据。数据库建立完毕后&#xff0c;由Flash向ASP提交请求&#xff0c;ASP根据请求对数据库进行操作后将结果返回给Flash&#xff0c;Flash以某种方式把结果显示出来。 …

国内首个!亚信安全获得CCRC数据分类分级产品认证证书

亚信安全信数数据分类分级系统AISDC V1.0&#xff0c;荣获中国网络安全审查认证和市场监管大数据中心颁发的首个数据分类分级产品IT产品信息安全认证证书&#xff01;标志着亚信安全在大数据安全领域的强大技术实力以及专业研究&#xff0c;正式获得国内数据分类分级产品评定的…

如何无公网ip实现SSH远程访问本地局域网openEuler系统?

文章目录 1. 本地SSH连接测试2. openEuler安装Cpolar3. 配置 SSH公网地址4. 公网远程SSH连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 欧拉操作系统(openEuler, 简称“欧拉”)是面向数字基础设施的操作系统,支持服务器、云计算、边缘openEuler是面向数字基础设施的操作系…

【Java】学习一门开发语言,从TA的Hello World开始

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《Java》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握…

晶振术语名词中英文对照及解析|晶发电子

在电子设备和通信系统中&#xff0c;精确的频率源是至关重要的。晶振作为频率源的核心元件&#xff0c;其性能直接影响着整个系统的稳定性、可靠性和准确性。随着技术的不断发展&#xff0c;对晶振的性能要求也越来越高。晶发电子将探讨晶振的常用术语及其含义&#xff0c;帮助…

java面试——juc篇

目录 一、线程基础 1、进程与线程的区别&#xff1f;&#xff08;⭐⭐⭐&#xff09; 2、并行和并发的区别&#xff08;⭐&#xff09; 3、创建线程的方式有哪些&#xff1f;&#xff08;⭐⭐⭐⭐&#xff09; runnable和Callable的区别&#xff1a; 线程中的run()和 star…

变电所运维可以实现一些什么功能

安科瑞武陈燕acrelcy 安科瑞AcrelCloud-1000变电所运维云平台 1.概述 基于互联网&#xff0b;、大数据、移动通讯等技术开发的云端管理平台&#xff0c;满足用户或运维公司监测众多变电所回路运行状态和参数、室内环境温湿度、电缆及母线运行温度、现场设备或环境场景等需求…