【并发编程】SemaphoreCountDownLatchCyclicBarrier

news2024/12/26 3:00:06

一、Semaphore

Semaphore 通常又被称为信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。

1.简单的使用

1-1.控制线程的并发连接数

 public static void main(String[] args) {
        // 只允许两个线程执行,其余线程要进行等待
        Semaphore semaphore = new Semaphore(2);
        // 创建了5个线程,但是同一时间只有两个线程可以执行
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+ ": acquire() time: " + System.currentTimeMillis());
                    Thread.sleep(1000); // 假设业务逻辑执行耗时1s
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

在这里插入图片描述

1-2.实现接口限流

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface InterfaceLimitAnno {

    String key();

    int limit() default 1;

}

@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@Slf4j
public class InterfaceLimitAspect {

    private static Map<String, Semaphore> map = new ConcurrentHashMap<>();

    @Pointcut("@annotation(com.example.practice.AOP.InterfaceLimitAnno)")
    public void validInterfaceLimit(){}

    @Around(value = "validInterfaceLimit()")
    public void around(ProceedingJoinPoint joinPoint)throws Throwable{
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        InterfaceLimitAnno annotation = signature.getMethod().getAnnotation(InterfaceLimitAnno.class);
        String key = annotation.key();
        int limit = annotation.limit();
        StringBuffer sb = new StringBuffer(key + "/" +signature.getMethod().getName());
        for (String parmName : signature.getParameterNames()) {
            sb.append(parmName);
        }
        Semaphore semaphore = map.get(sb.toString());
        if (semaphore == null) {
            semaphore= new Semaphore(limit);
            map.put(sb.toString(), semaphore);
        }
        try {
            boolean b = semaphore.tryAcquire();
            if (b) {
                joinPoint.proceed();
            } else {
                throw new Exception("访问超出上限,请稍后重试");
            }
        } finally {
            semaphore.release();
        }

    }

}

2.底层实现

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

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package java.util.concurrent;

import java.io.Serializable;
import java.util.Collection;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class Semaphore implements Serializable {
    private static final long serialVersionUID = -3222578661600680210L;
    private final Semaphore.Sync sync;

    public Semaphore(int var1) {
        this.sync = new Semaphore.NonfairSync(var1);
    }

    public Semaphore(int var1, boolean var2) {
        this.sync = (Semaphore.Sync)(var2 ? new Semaphore.FairSync(var1) : new Semaphore.NonfairSync(var1));
    }

    // 支持中断,state=state-1;中断后会抛出异常
    public void acquire() throws InterruptedException {
        this.sync.acquireSharedInterruptibly(1);
    }

    // 不支持中断,没有异常信息抛出
    public void acquireUninterruptibly() {
        this.sync.acquireShared(1);
    }

    public boolean tryAcquire() {
        return this.sync.nonfairTryAcquireShared(1) >= 0;
    }

    // 等待var3后不再等待,释放CPU的占用,执行降级方案
    public boolean tryAcquire(long var1, TimeUnit var3) throws InterruptedException {
        return this.sync.tryAcquireSharedNanos(1, var3.toNanos(var1));
    }

    public void release() {
        this.sync.releaseShared(1);
    }

    // 指定占用的资源,state=state-var1
    public void acquire(int var1) throws InterruptedException {
        if (var1 < 0) {
            throw new IllegalArgumentException();
        } else {
            this.sync.acquireSharedInterruptibly(var1);
        }
    }

    public void acquireUninterruptibly(int var1) {
        if (var1 < 0) {
            throw new IllegalArgumentException();
        } else {
            this.sync.acquireShared(var1);
        }
    }

    public boolean tryAcquire(int var1) {
        if (var1 < 0) {
            throw new IllegalArgumentException();
        } else {
            return this.sync.nonfairTryAcquireShared(var1) >= 0;
        }
    }

    public boolean tryAcquire(int var1, long var2, TimeUnit var4) throws InterruptedException {
        if (var1 < 0) {
            throw new IllegalArgumentException();
        } else {
            return this.sync.tryAcquireSharedNanos(var1, var4.toNanos(var2));
        }
    }

    public void release(int var1) {
        if (var1 < 0) {
            throw new IllegalArgumentException();
        } else {
            this.sync.releaseShared(var1);
        }
    }

    public int availablePermits() {
        return this.sync.getPermits();
    }

    public int drainPermits() {
        return this.sync.drainPermits();
    }

    protected void reducePermits(int var1) {
        if (var1 < 0) {
            throw new IllegalArgumentException();
        } else {
            this.sync.reducePermits(var1);
        }
    }

    public boolean isFair() {
        return this.sync instanceof Semaphore.FairSync;
    }

    public final boolean hasQueuedThreads() {
        return this.sync.hasQueuedThreads();
    }

    public final int getQueueLength() {
        return this.sync.getQueueLength();
    }

    protected Collection<Thread> getQueuedThreads() {
        return this.sync.getQueuedThreads();
    }

    public String toString() {
        return super.toString() + "[Permits = " + this.sync.getPermits() + "]";
    }

    static final class FairSync extends Semaphore.Sync {
        private static final long serialVersionUID = 2014338818796000944L;

        FairSync(int var1) {
            super(var1);
        }

        protected int tryAcquireShared(int var1) {
            int var2;
            int var3;
            do {
                if (this.hasQueuedPredecessors()) {
                    return -1;
                }

                var2 = this.getState();
                var3 = var2 - var1;
            } while(var3 >= 0 && !this.compareAndSetState(var2, var3));

            return var3;
        }
    }

    static final class NonfairSync extends Semaphore.Sync {
        private static final long serialVersionUID = -2694183684443567898L;

        NonfairSync(int var1) {
            // 将state设置为2
            super(var1);
        }

        protected int tryAcquireShared(int var1) {
            return this.nonfairTryAcquireShared(var1);
        }
    }

    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 1192457210091910933L;

        Sync(int var1) {
            this.setState(var1);
        }

        final int getPermits() {
            return this.getState();
        }

        final int nonfairTryAcquireShared(int var1) {
            int var2;
            int var3;
            do {
                // 加锁的时候state=state-1
                var2 = this.getState();
                var3 = var2 - var1;
            } while(var3 >= 0 && !this.compareAndSetState(var2, var3)); // 更新state

            return var3;
        }

        protected final boolean tryReleaseShared(int var1) {
            int var2;
            int var3;
            do {
                var2 = this.getState();
                var3 = var2 + var1;
                if (var3 < var2) {
                    throw new Error("Maximum permit count exceeded");
                }
            } while(!this.compareAndSetState(var2, var3));

            return true;
        }

        final void reducePermits(int var1) {
            int var2;
            int var3;
            do {
                var2 = this.getState();
                var3 = var2 - var1;
                if (var3 > var2) {
                    throw new Error("Permit count underflow");
                }
            } while(!this.compareAndSetState(var2, var3));

        }

        final int drainPermits() {
            int var1;
            do {
                var1 = this.getState();
            } while(var1 != 0 && !this.compareAndSetState(var1, 0));

            return var1;
        }
    }
}
        

2-1.Semaphore.acquire()
在这里插入图片描述

 static final class NonfairSync extends Semaphore.Sync {
        private static final long serialVersionUID = -2694183684443567898L;

        NonfairSync(int var1) {
            //  Semaphore semaphore = new Semaphore(2);默认创建的是非公平锁,将state设置为2
            super(var1);
        }
        
        // 加锁: semaphore.acquire()
        protected int tryAcquireShared(int var1) {
            return this.nonfairTryAcquireShared(var1);
        }
    }

abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 1192457210091910933L;

        Sync(int var1) {
            this.setState(var1);
        }

        final int getPermits() {
            return this.getState();
        }

        final int nonfairTryAcquireShared(int var1) {
            int var2;
            int var3;
            do {
                // state = state - 1;如果state>0则说明还有可用的资源,反之则需要将线程入队
                var2 = this.getState();
                var3 = var2 - var1;
            } while(var3 >= 0 && !this.compareAndSetState(var2, var3));

            return var3;
        }
        ......
   }
private void doAcquireSharedInterruptibly(int var1) throws InterruptedException {
        AbstractQueuedSynchronizer.Node var2 = this.addWaiter(AbstractQueuedSynchronizer.Node.SHARED);
        boolean var3 = true;

        try {
            AbstractQueuedSynchronizer.Node var4;
            do {
                var4 = var2.predecessor();
                if (var4 == this.head) {//如果当前线程的前置节点是head,则在入队前再尝试一次加锁
                    int var5 = this.tryAcquireShared(var1);
                    if (var5 >= 0) { // 加锁成功,则当前线程的节点成为head节点
                        this.setHeadAndPropagate(var2, var5);
                        var4.next = null;
                        var3 = false;
                        return;
                    }
                }
              //shouldParkAfterFailedAcquire(var4, var2): waitStatus由0变为-1  
              // this.parkAndCheckInterrupt():当前线程被阻塞
            } while(!shouldParkAfterFailedAcquire(var4, var2) || !this.parkAndCheckInterrupt());

            throw new InterruptedException();
        } finally {
            if (var3) {
                this.cancelAcquire(var2);
            }

        }
    }

2-2.Semaphore.release()
在这里插入图片描述

 protected final boolean tryReleaseShared(int var1) {
            int var2;
            int var3;
            do {
                var2 = this.getState();
                var3 = var2 + var1;
                if (var3 < var2) {
                    throw new Error("Maximum permit count exceeded");
                }
            } while(!this.compareAndSetState(var2, var3));

            return true;
        }

 private void doReleaseShared() {
        while(true) {
            AbstractQueuedSynchronizer.Node var1 = this.head;
            if (var1 != null && var1 != this.tail) {
                int var2 = var1.waitStatus;
                if (var2 == -1) {
                    if (!compareAndSetWaitStatus(var1, -1, 0)) {
                        continue;
                    }

                    this.unparkSuccessor(var1);
                } else if (var2 == 0 && !compareAndSetWaitStatus(var1, 0, -3)) {
                    continue;
                }
            }

            if (var1 == this.head) {
                return;
            }
        }
    }

 private void unparkSuccessor(AbstractQueuedSynchronizer.Node var1) {
        int var2 = var1.waitStatus;
        if (var2 < 0) {
            compareAndSetWaitStatus(var1, var2, 0);
        }

        AbstractQueuedSynchronizer.Node var3 = var1.next;
        if (var3 == null || var3.waitStatus > 0) {
            var3 = null;

            for(AbstractQueuedSynchronizer.Node var4 = this.tail; var4 != null && var4 != var1; var4 = var4.prev) {
                if (var4.waitStatus <= 0) {
                    var3 = var4;
                }
            }
        }

        if (var3 != null) {
            LockSupport.unpark(var3.thread);
        }

    }

二、CountDownLatch

CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。

1.简单的使用

 public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        Thread t1 = new Thread(() -> {
            try {
                System.out.println("t1线程运行中");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        });
        Thread t2 = new Thread(() -> {
            try {
                System.out.println("t2线程运行中");
            } finally {
                countDownLatch.countDown();
            }
        });
        t1.start();
        t2.start();
        countDownLatch.await();
        System.out.println("t1、t2线程运行完成");
    }

在这里插入图片描述

2.底层实现

在这里插入图片描述

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package java.util.concurrent;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class CountDownLatch {
    private final CountDownLatch.Sync sync;

    public CountDownLatch(int var1) {
        if (var1 < 0) {
            throw new IllegalArgumentException("count < 0");
        } else {
            this.sync = new CountDownLatch.Sync(var1);
        }
    }

    public void await() throws InterruptedException {
        this.sync.acquireSharedInterruptibly(1);
    }

    public boolean await(long var1, TimeUnit var3) throws InterruptedException {
        return this.sync.tryAcquireSharedNanos(1, var3.toNanos(var1));
    }

    public void countDown() {
        this.sync.releaseShared(1);
    }

    public long getCount() {
        return (long)this.sync.getCount();
    }

    public String toString() {
        return super.toString() + "[Count = " + this.sync.getCount() + "]";
    }

    private static final class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 4982264981922014374L;

        Sync(int var1) {
            this.setState(var1);
        }

        int getCount() {
            return this.getState();
        }

        protected int tryAcquireShared(int var1) {
            return this.getState() == 0 ? 1 : -1;
        }

        protected boolean tryReleaseShared(int var1) {
            int var2;
            int var3;
            do {
                var2 = this.getState();
                if (var2 == 0) {
                    return false;
                }

                var3 = var2 - 1;
            } while(!this.compareAndSetState(var2, var3));

            return var3 == 0;
        }
    }
}

2-1. countDownLatch.await():全部子线程执行完成后,执行汇总逻辑

 public void await() throws InterruptedException {
        this.sync.acquireSharedInterruptibly(1);
    }

public final void acquireSharedInterruptibly(int var1) throws InterruptedException {
        if (Thread.interrupted()) {
            throw new InterruptedException();
        } else {
            if (this.tryAcquireShared(var1) < 0) { // state == 0 ? 1 : -1 ,与var1没什么关系
                this.doAcquireSharedInterruptibly(var1); // 线程阻塞
            }

        }
    }

private void doAcquireSharedInterruptibly(int var1) throws InterruptedException {
        AbstractQueuedSynchronizer.Node var2 = this.addWaiter(AbstractQueuedSynchronizer.Node.SHARED);
        boolean var3 = true;

        try {
            AbstractQueuedSynchronizer.Node var4;
            do {
                var4 = var2.predecessor();
                if (var4 == this.head) {
                    int var5 = this.tryAcquireShared(var1);
                    if (var5 >= 0) {
                        this.setHeadAndPropagate(var2, var5);
                        var4.next = null;
                        var3 = false;
                        return;
                    }
                }
            } while(!shouldParkAfterFailedAcquire(var4, var2) || !this.parkAndCheckInterrupt());

            throw new InterruptedException();
        } finally {
            if (var3) {
                this.cancelAcquire(var2);
            }

        }
    }    

2-2. countDownLatch.countDown()

 public void countDown() {
        this.sync.releaseShared(1);
    }

  public final boolean releaseShared(int var1) {
        if (this.tryReleaseShared(var1)) { // state=state-1,如果state不为0则不会唤醒当前阻塞的线程
            this.doReleaseShared(); // 将waitStatus由-1转化为0,唤醒阻塞的线程
            return true;
        } else {
            return false;
        }
    }

protected boolean tryReleaseShared(int var1) {
            int var2;
            int var3;
            do {
                var2 = this.getState();
                if (var2 == 0) {
                    return false;
                }

                var3 = var2 - 1;
            } while(!this.compareAndSetState(var2, var3));

            return var3 == 0;
        }
        
 private void doReleaseShared() {
        while(true) {
            AbstractQueuedSynchronizer.Node var1 = this.head;
            if (var1 != null && var1 != this.tail) {
                int var2 = var1.waitStatus;
                if (var2 == -1) {
                    if (!compareAndSetWaitStatus(var1, -1, 0)) {
                        continue;
                    }

                    this.unparkSuccessor(var1);
                } else if (var2 == 0 && !compareAndSetWaitStatus(var1, 0, -3)) {
                    continue;
                }
            }

            if (var1 == this.head) {
                return;
            }
        }
    }

三、CyclicBarrier

栅栏屏障,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。

1.简单的使用

 public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(10, new Runnable() {
            @Override
            public void run() {
                System.out.println("所有线程都到达,任务开始执行");
            }
        });
        for (int i = 0; i < 10; i++) {
           new Thread(() -> {
               try {
                   System.out.println(Thread.currentThread().getName() +"到达,开始执行自己的业务逻辑");
                   Thread.sleep(1000);
                   cyclicBarrier.await();
                   System.out.println(Thread.currentThread().getName() +"开始执行业务的整合逻辑");
               } catch (InterruptedException e) {
                   e.printStackTrace();
               } catch (BrokenBarrierException e) {
                   e.printStackTrace();
               }
           }).start();
        }
    }

在这里插入图片描述

2.底层实现

在这里插入图片描述

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package java.util.concurrent;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class CyclicBarrier {
    // 用于保护屏障入口的锁
    private final ReentrantLock lock;
    // 达到屏障并且不能放行的线程在trip条件变量上等待
    private final Condition trip;
    // 栅栏开启需要的到达线程总数
    private final int parties;
    // 最后一个线程到达屏障后执行的回调任务
    private final Runnable barrierCommand;
    // 这是一个内部类,通过它实现CyclicBarrier重复利用,每当await达到最大次数的时候,就会重新new 一个,表示进入了下一个轮回。里面只有一个boolean型属性,用来表示当前轮回是否有线程中断。
    private CyclicBarrier.Generation generation;
    private int count;

    private void nextGeneration() {
        this.trip.signalAll();
        this.count = this.parties;
        this.generation = new CyclicBarrier.Generation();
    }

    private void breakBarrier() {
        this.generation.broken = true;
        this.count = this.parties;
        this.trip.signalAll();
    }

    private int dowait(boolean var1, long var2) throws InterruptedException, BrokenBarrierException, TimeoutException {
        ReentrantLock var4 = this.lock;
        var4.lock();

        byte var9;
        try {
            CyclicBarrier.Generation var5 = this.generation;
            if (var5.broken) {
                throw new BrokenBarrierException();
            }

            if (Thread.interrupted()) {
                this.breakBarrier();
                throw new InterruptedException();
            }

            int var6 = --this.count;
            if (var6 != 0) {
                do {
                    try {
                        if (!var1) {
                            this.trip.await();
                        } else if (var2 > 0L) {
                            var2 = this.trip.awaitNanos(var2);
                        }
                    } catch (InterruptedException var19) {
                        if (var5 == this.generation && !var5.broken) {
                            this.breakBarrier();
                            throw var19;
                        }

                        Thread.currentThread().interrupt();
                    }

                    if (var5.broken) {
                        throw new BrokenBarrierException();
                    }

                    if (var5 != this.generation) {
                        int var21 = var6;
                        return var21;
                    }
                } while(!var1 || var2 > 0L);

                this.breakBarrier();
                throw new TimeoutException();
            }

            boolean var7 = false;

            try {
                Runnable var8 = this.barrierCommand;
                if (var8 != null) {
                    var8.run();
                }

                var7 = true;
                this.nextGeneration();
                var9 = 0;
            } finally {
                if (!var7) {
                    this.breakBarrier();
                }

            }
        } finally {
            var4.unlock();
        }

        return var9;
    }

    public CyclicBarrier(int var1, Runnable var2) {
        this.lock = new ReentrantLock();
        this.trip = this.lock.newCondition();
        this.generation = new CyclicBarrier.Generation();
        if (var1 <= 0) {
            throw new IllegalArgumentException();
        } else {
            this.parties = var1;
            this.count = var1;
            this.barrierCommand = var2;
        }
    }

    public CyclicBarrier(int var1) {
        this(var1, (Runnable)null);
    }

    public int getParties() {
        return this.parties;
    }

    public int await() throws InterruptedException, BrokenBarrierException {
        try {
            return this.dowait(false, 0L);
        } catch (TimeoutException var2) {
            throw new Error(var2);
        }
    }

    public int await(long var1, TimeUnit var3) throws InterruptedException, BrokenBarrierException, TimeoutException {
        return this.dowait(true, var3.toNanos(var1));
    }

    public boolean isBroken() {
        ReentrantLock var1 = this.lock;
        var1.lock();

        boolean var2;
        try {
            var2 = this.generation.broken;
        } finally {
            var1.unlock();
        }

        return var2;
    }

    public void reset() {
        ReentrantLock var1 = this.lock;
        var1.lock();

        try {
            this.breakBarrier();
            this.nextGeneration();
        } finally {
            var1.unlock();
        }

    }

    public int getNumberWaiting() {
        ReentrantLock var1 = this.lock;
        var1.lock();

        int var2;
        try {
            var2 = this.parties - this.count;
        } finally {
            var1.unlock();
        }

        return var2;
    }

    private static class Generation {
        boolean broken;

        private Generation() {
            this.broken = false;
        }
    }
}

2-1.public CyclicBarrier(int var1, Runnable var2)

 public CyclicBarrier(int var1, Runnable var2) {
        this.lock = new ReentrantLock();
        this.trip = this.lock.newCondition();
        this.generation = new CyclicBarrier.Generation();
        if (var1 <= 0) {
            throw new IllegalArgumentException();
        } else {
            this.parties = var1;
            this.count = var1;
            this.barrierCommand = var2;
        }
    }

2-2.cyclicBarrier.await()

   public int await() throws InterruptedException, BrokenBarrierException {
        try {
            return this.dowait(false, 0L);
        } catch (TimeoutException var2) {
            throw new Error(var2);
        }
    }

private int dowait(boolean var1, long var2) throws InterruptedException, BrokenBarrierException, TimeoutException {
        ReentrantLock var4 = this.lock;
        var4.lock();

        byte var9;
        try {
            CyclicBarrier.Generation var5 = this.generation;
            if (var5.broken) {
                throw new BrokenBarrierException();
            }

            if (Thread.interrupted()) {
                this.breakBarrier();
                throw new InterruptedException();
            }

            int var6 = --this.count;
            if (var6 != 0) {
                do {
                    try {
                        if (!var1) {
                            // 当前线程阻塞
                            this.trip.await();
                        } else if (var2 > 0L) {
                            var2 = this.trip.awaitNanos(var2);
                        }
                    } catch (InterruptedException var19) {
                        if (var5 == this.generation && !var5.broken) {
                            this.breakBarrier();
                            throw var19;
                        }

                        Thread.currentThread().interrupt();
                    }

                    if (var5.broken) {
                        throw new BrokenBarrierException();
                    }

                    if (var5 != this.generation) {
                        int var21 = var6;
                        return var21;
                    }
                } while(!var1 || var2 > 0L);

                this.breakBarrier();
                throw new TimeoutException();
            }

            boolean var7 = false;

            try {
                Runnable var8 = this.barrierCommand;
                if (var8 != null) {
                    var8.run();
                }

                var7 = true;
                // count=0 唤醒所有的线程
                this.nextGeneration();
                var9 = 0;
            } finally {
                if (!var7) {
                    this.breakBarrier();
                }

            }
        } finally {
            var4.unlock();
        }

        return var9;
    }

  private void nextGeneration() {
        this.trip.signalAll();
        this.count = this.parties;
        this.generation = new CyclicBarrier.Generation();
    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中英翻译《动物看见了什么》

What animals see 动物看见了什么 一、Pre-reading activity 阅前思考 1.What animals do you like? 你喜欢什么动物&#xff1f; 2.Do you have any animals in your home? 你家里有动物吗&#xff1f; 3.Do you think most animals can see as well as we can? 你认为大多…

Windows下docker安装

安装 1.打开Hyper-V &#xff0c;在"启用或关闭Windows功能" 如果这里的Hyper-V平台灰色不能勾选 显示无法安装Hyper-v该固件中的虚拟化支持被禁用&#xff0c;则需要开启 开始方式&#xff1a; 重启电脑进入BIOSS界面 点击高级–>CPU设置 —> Intel virtu…

44. python的for循环嵌套

44. python的for循环嵌套 文章目录44. python的for循环嵌套1. 什么是嵌套2. for循环中嵌套有if条件判断语句2.1 先创建一个奇数序列2.2 判断一个数是否能被7整除2.3 将2部分代码合二为一3. for循环中嵌套有for循环1. 什么是嵌套 嵌套是指一个对象中包含另一个与它相似的对象。…

Python 中在两个字典中查找公共键

Python 中要在两个词典中查找公共键&#xff1a; 使用 dict.keys() 方法获取每个字典的键的视图对象。使用 & 符号获取常用键。使用 list() 类将结果转换为列表对象。 dict1 {name: jiyik, topic: Python, salary: 100} dict2 {name: alice, salary: 100, experience: …

R语言探索BRFSS数据可视化

设定 加载包 最近我们被客户要求撰写关于BRFSS数据的研究报告&#xff0c;包括一些图形和统计输出。在本实验中&#xff0c;我们将使用dplyr软件包探索数据&#xff0c;并使用ggplot2软件包对其进行可视化以进行数据可视化 library(ggplot2) library(dplyr) 载入资料 load…

初识Netty框架

总体概述 Netty作为一款网络通信框架&#xff0c;底层封装了NIO。我们在使用Netty时&#xff0c;无需再关注NIO细节。下图为Netty处理流程图&#xff1a; 应用程序中使用Netty作为网络通信框架后&#xff0c;会形成一条PipeLine链&#xff0c;PipeLine链上有一个一个的事件处…

buuctf10(异或注入中文字符绕过preg_match伪随机数漏洞seed)

目录 [WUSTCTF2020] 颜值成绩(异或注入) [Zer0pts2020]Can you guess it?(中文字符绕过preg_match) [FBCTF2019]RCEService(/bin/调用命令 || 回溯绕过preg_match) [GKCTF 2021]easycms(后台弱口令&任意文件下载) [GWCTF 2019]枯燥的抽奖(伪随机数漏洞seed) [MRCTF20…

msprofiler 性能调优命令行实战(口罩识别推理)

案例介绍 本案例使用口罩识别推理程序作为例子进行演示&#xff0c;硬件平台是华为昇腾310设备(Ascend 310)&#xff0c;该口罩识别使用目标检测中SSD模型&#xff0c;检测的结果有两个类别&#xff1a;戴口罩的脸、没带口罩的脸。成功执行推理程序后我们对其进行了推理调优&a…

连续7年领跑!在华为云桌面,藏了一盘数字办公的大棋

作者 | 曾响铃 文 | 响铃说 连续7年领跑&#xff01;在国内虚拟客户端计算软件市场&#xff0c;华为云再度占据行业第一的位置&#xff0c;力压Citrix、Microsoft和VMware等全球知名厂商。 所谓的虚拟客户端计算软件市场&#xff0c;简单来理解就是云桌面市场。伴随着数字办…

Oracle报错:ORA-28001:口令已失效

一、链接Oracle报错 &#xff1a;ORA-28001&#xff1a;口令已失效 解决办法 原因&#xff1a;Oracle11G创建用户时缺省密码过期限制是180天&#xff08;即6个月&#xff09;&#xff0c; 如果超过180天用户密码未做修改则该用户无法登录 解决方式&#xff1a; 方式一&#xf…

R语言可视化探索BRFSS数据并逻辑回归Logistic回归预测中风

第1部分&#xff1a;关于数据 行为风险因素监视系统&#xff08;BRFSS&#xff09;是美国的年度电话调查。最近我们被客户要求撰写关于BRFSS的研究报告&#xff0c;包括一些图形和统计输出。BRFSS旨在识别成年人口中的危险因素并报告新兴趋势。例如&#xff0c;询问受访者饮食…

Python 并发编程

一.Python 对并发编程的支持 多线程&#xff1a;threading&#xff0c;利用CPU和IO可同时执行的原理&#xff0c;让CPU不会干巴巴等待IO完成&#xff0c;而是切换到其他Task&#xff08;任务&#xff09;&#xff0c;进行多线程的执行。多进程&#xff1a;multiprocessing&…

微前端总结

微前端概述 微前端概念是从微服务概念扩展而来的&#xff0c;摒弃大型单体方式&#xff0c;将前端整体分解为小而简单的块&#xff0c;这些块可以独立开发、测试和部署&#xff0c;同时仍然聚合为一个产品出现在客户面前。可以理解微前端是一种将多个可独立交付的小型前端应用…

使用极限学习机进行股市预测(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 极限学习机&#xff08;Extreme Learning Machine,ELM&#xff09;作为前馈神经网络学习中一种全新的训练框架,在行为识别、情…

EPICS -- 使用asynPortDriver类编写示一个示例程序

本示例展示了如何使用asynPortDriver类编写一个EPICS端口驱动程序的示例。 这个驱动程序参数库中一个有5个参数&#xff0c;分别支持5个EPICS记录。 如下是具体步骤&#xff1a; 1&#xff09; 用makeBaseApp.pl脚本建立这个IOC应用程序的框架&#xff1a; [blctrlmain-mach…

IDEA中如何实现git的cherry-pick可视化操作?

目录 问题现象&#xff1a; 问题分析&#xff1a; 解决方法&#xff1a; 拓展&#xff1a;如何回退提交记录&#xff1f; 问题现象&#xff1a; 今天在学习了git的cherry-pick功能&#xff0c;于是引出了一个问题&#xff1a; IDEA中如何实现git的cherry-pick可视化操作&am…

【Docker学习教程系列】7-如何将本地的Docker镜像发布到阿里云

在上一篇中&#xff0c;我们使用docker commit 命令&#xff0c;创建了一个带有vim的Ubuntu镜像。那么怎么将这个镜像分享出去呢&#xff1f;本文就来讲解如何将本地的docker镜像发布到阿里云上。 本文主要内容&#xff1a; 1&#xff1a;本地镜像发布到阿里云流程 2&#xf…

Linux网络原理与编程(4)——第十四节 传输层协议

目录 前置知识 再谈端口号 几个函数 netstat telnet UDP报文 UDP协议端格式 UDP首部&#xff1a; UDP的特点 UDP的缓冲区 TCP报文详解 Tcp报头详解 传输层是在应用层的下面一层&#xff0c;我们在讲解传输层协议之前&#xff0c;先来说一说一些前置知识即命令函数等…

看完就会flink基础API

文章目录一、执行环境&#xff08;Execution Environment&#xff09;1、创建执行环境2、执行模式(Execution Mode)3、触发程序执行二、源算子&#xff08;Source&#xff09;1、数据源类准备2、从集合中读取数据3、从文件中读取数据4、从Socket中读取数据5、从Kafka中读取数据…

ISCSLP 2022 Program|希尔贝壳邀您参加第十三届中文口语语言处理国际会议

第十三届中文口语语言处理国际会议将于2022年12月11-14日&#xff08;本周日~下周三&#xff09;正式开启&#xff0c;本次会议中的部分Session将通过语音之家视频号进行线上直播&#xff0c;欢迎大家参加&#xff01; 官网&#xff1a;www.iscslp2022.org 大会简介 中文口语…