JUC编程

2023-11-18

1 JUC

JUC就是java.util .concurrent工具包的简称。这是一个处理线程的工具包,JDK 1.5开始出现的

1 传统的synchronized


public class Synchronized {
    public static void main(String[] args) {

        //并发 : 多个线程同时操作同一个资源类
        // 使用lambda表达式进行解耦,将资源类丢入线程的执行
        Person person = new Person();

        new  Thread(()->{
                for (int i = 0 ;i < 60 ; i ++){
                    person.sale();
                }

        }).start();
        new  Thread(()->{
            for (int i = 0 ;i < 60 ; i ++){
                person.sale();
            }

        }).start();
        new  Thread(()->{
            for (int i = 0 ;i < 60 ; i ++){
                person.sale();
            }
        }).start();



    }
}

// 加锁时需要判断条件,进行锁定
// 使用lambda表达式进行解耦

//资源类
class  Person{
    private int numbers =50 ;


    public synchronized void sale(){
        if(numbers > 0) {
            System.out.println("" + Thread.currentThread().getName() + "买了第" + numbers-- + "还剩" + numbers + "张");
        }
    }

}

2 Lock 接口
在这里插入图片描述
常用 可重入锁

public class Synchronized {
    public static void main(String[] args) {

        //并发 : 多个线程同时操作同一个资源类
        // 使用lambda表达式进行解耦,将资源类丢入线程的执行
        Person person = new Person();

        new  Thread(()->{
                for (int i = 0 ;i < 60 ; i ++){
                    person.sale();
                }

        }).start();
        new  Thread(()->{
            for (int i = 0 ;i < 60 ; i ++){
                person.sale();
            }

        }).start();
        new  Thread(()->{
            for (int i = 0 ;i < 60 ; i ++){
                person.sale();
            }
        }).start();



    }
}

// 加锁时需要判断条件,进行锁定
// 使用lambda表达式进行解耦

//资源类
/*
    Lock
* 1   new ReentrantLock();
  2   加锁   lock.lock();
* 3    代码包裹在try块 之内
* 4    在  finally 块 解锁  lock.unlock();
*
* */
class  Person{
    private int numbers =50 ;
   Lock lock = new ReentrantLock();

    public synchronized void sale(){
        lock.lock();

        try {
            if(numbers > 0) {
                System.out.println("" + Thread.currentThread().getName() + "买了第" + numbers-- + "还剩" + numbers + "张");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
              lock.unlock();
        }
    }

}

Lock

  • 1 new ReentrantLock();
    2 加锁 lock.lock();
  • 3 代码包裹在try块 之内
  • 4 在 finally 块 解锁 lock.unlock();

两种锁机制的不同
1 synchronized 是Java内置关键字,Lock 是一个接口
2 synchronized 无法判断是否获取锁,Lock 可以判断是否获取锁
3 synchronized 可以自动释放锁,Lock 必须手动释放锁,如果不释放就会造成死锁
4 同一个锁对象,线程A synchronized获取之后,线程B只能等待,造成阻塞,Lock 并不会等待
5 synchronized 可重入锁,不可中断,非公平锁,Lock 可重入锁,可以判断,非公平锁(可设置)
6 synchronized 适合少量同步代码,Lock 适合大量同步代码

消费者和生产者问题

1 传统的synchronized

//消费生产三步骤
// 等待 业务 通知

public class SynchronizedPc {
    public static void main(String[] args) {

        Data d = new Data();

        new Thread(()->{
            try {
                for (int i = 0; i <10 ; i++) {

                    d.increment();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();

        new Thread(()->{
            try {
                for (int i = 0; i < 10; i++) {

                    d.decrement();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();


    }
}


class Data{
    private int number ;


    public synchronized   void  increment() throws InterruptedException {
        if(number != 0){

            this.wait();
        }
        number++;
        this.notifyAll();
        System.out.println(Thread.currentThread().getName()+"->"+number);
    }

    public synchronized   void  decrement() throws InterruptedException {
        if(number == 0){

            this.wait();
        }
        number--;
        this.notifyAll();

        System.out.println(Thread.currentThread().getName()+"->"+number);
    }
}

在这里插入图片描述
多个生产者和消费者的情况下
等待时使用if判断,会造成虚假唤醒,因为if语句只判断一次,当生产者进行等待释放锁之后,消费者进行消费,消费完成之后,唤醒了所有生产者线程,生产者线程在释放锁之后的代码继续执行则跳过了if判断(wait()方法释放锁之后再获取锁会在释放锁之后的代码继续执行
解决办法 : 使用while循环 ,进行循环判断

//消费生产三步骤
// 等待 业务 通知 
class Data{
    private int number ;


    public synchronized   void  increment() throws InterruptedException {
       while (number != 0){

           this.wait();
       }
        number++;
        this.notifyAll();
        System.out.println(Thread.currentThread().getName()+"->"+number);
    }

    public synchronized   void  decrement() throws InterruptedException {
        while (number == 0){
            
            this.wait();
        }
        number--;
        this.notifyAll();

        System.out.println(Thread.currentThread().getName()+"->"+number);
    }
}

Lock 实现
在这里插入图片描述

public class SynchronizedPc {
    public static void main(String[] args) {

        Data2 d = new Data2();

        new Thread(()->{
            try {
                for (int i = 0; i <30 ; i++) {

                    d.increment();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();

        new Thread(()->{
            try {
                for (int i = 0; i < 30; i++) {

                    d.decrement();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();

        new Thread(()->{
            try {
                for (int i = 0; i <30 ; i++) {

                    d.increment();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"C").start();

        new Thread(()->{
            try {
                for (int i = 0; i <30 ; i++) {

                    d.decrement();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"D").start();


    }
}


class Data2{
    private int number ;

    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    public    void  increment() throws InterruptedException {
                            //流程
        lock.lock();      //1  加锁

        try {                     //2 try块包裹业务代码
            while (number != 0){
                condition.await();   
            }
            number++;
            condition.signalAll();
            System.out.println(Thread.currentThread().getName()+"->"+number);
        } finally {
           lock.unlock();       //3  finally块 解锁
        }
    }

    public    void  decrement() throws InterruptedException {
        lock.lock(); 
        try {
            while (number == 0){
              condition.await();
            }
            number--;
            condition.signalAll();
            System.out.println(Thread.currentThread().getName()+"->"+number);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

Lock 锁比传统的synchronized 多精准唤醒功能

public class SynchronizedPc {
    public static void main(String[] args) {

        Data3 d = new Data3();

        new Thread(()->{
            try {
                for (int i = 0; i <30 ; i++) {

                    d.incrementA();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();

        new Thread(()->{
            try {
                for (int i = 0; i < 30; i++) {

                    d.decrementB();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();

        new Thread(()->{
            try {
                for (int i = 0; i <30 ; i++) {

                    d.incrementC();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"C").start();

        new Thread(()->{
            try {
                for (int i = 0; i <30 ; i++) {

                    d.decrementD();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"D").start();


    }
}


class Data3{
    private int number ;

   private Lock lock = new ReentrantLock();
   private Condition condition1= lock.newCondition();
   private Condition condition2= lock.newCondition();
   private Condition condition3 = lock.newCondition();
    private Condition condition4 = lock.newCondition();

    public    void  incrementA() throws InterruptedException {
        //流程
        lock.lock();      //1  加锁

        try {                     //2 try块包裹业务代码
            while (number != 0){
                condition1.await();
            }
            number++;
            condition2.signal();
            System.out.println(Thread.currentThread().getName()+"->"+number);
        } finally {
            lock.unlock();       //3  finally块 解锁
        }
    }

    public    void  decrementB() throws InterruptedException {
        lock.lock();
        try {
            while (number == 0){
                condition2.await();
            }
            number--;
            condition3.signal();
            System.out.println(Thread.currentThread().getName()+"->"+number);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public    void  incrementC() throws InterruptedException {
        //流程
        lock.lock();      //1  加锁

        try {                     //2 try块包裹业务代码
            while (number != 0){
                condition3.await();
            }
            number++;
            condition4.signal();
            System.out.println(Thread.currentThread().getName()+"->"+number);
        } finally {
            lock.unlock();       //3  finally块 解锁
        }
    }

    public    void  decrementD() throws InterruptedException {
        lock.lock();
        try {
            while (number == 0){
                condition4.await();
            }
            number--;
            condition1.signal();
            System.out.println(Thread.currentThread().getName()+"->"+number);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}

精准唤醒总结:有几个线程就有几个监视器,由不同的监视器来唤醒不同的线程;A个监视器在A线程等待时,在其他线程使用A监视器唤醒时就会唤醒等待的A线程

3 八锁现象
锁有两种
1 new 出来的实例对象
2 Class 类模板

synchronized :锁的是方法的调用者
static : 锁的是Class 类对象

总结:当线程之间的锁对象不同时,按照时间来进行判断那一个先执行;当线程之间的锁对象相同时,有阻塞现象产生,先获取锁对象的先执行

4 线程不安全集合解决方法

4.1 List
在这里插入图片描述
4.2 Set
在这里插入图片描述
在这里插入图片描述
4.3 Map
在这里插入图片描述
5 Callable 与 Thread
在这里插入图片描述
细节:
1 FutureTask是Runable接口的实现类,FutureTask可以接受Callable接口,所以FutureTask相当于Thread类和Callable接口的适配类
2 Callable 接口中的call()方法有返回值,也可以抛出异常
3 Callable接口的call()方法有缓存
4 返回值可能会阻塞

6 JUC辅助类(必会)
6.1
在这里插入图片描述
6.2
在这里插入图片描述
6.3
在这里插入图片描述
在这里插入图片描述
7 ReadWriteLock接口

ReadWriteLock(唯一实现类)维护一对关联的locks ,一个用于只读操作,一个用于写入。 read lock可以由多个阅读器线程同时进行,只要没有作者。 write lock是独家的

在这里插入图片描述
8 阻塞队列
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
BlockingQueue
使用场景:线程池,多线程并发处理

四组API
在这里插入图片描述
9 线程池
池化技术:某一个资源频繁的创建和销毁,非常耗费内存;
将资源重复利用,减少资源频繁的创建和销毁

优势
1 降低资源的消耗
2 提高响应速度
3 方便管理

9.1 三大方法
在这里插入图片描述
9.2 七大参数
源码分析

 public static ExecutorService newSingleThreadExecutor() {
        return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
    }

public static ExecutorService newFixedThreadPool(int var0) {
        return new ThreadPoolExecutor(var0, var0, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
    }
 public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, 2147483647, 60L, TimeUnit.SECONDS, new SynchronousQueue());
    }

底层都是用的ThreadPoolExecuto类

七大参数
var1  :核心线程数
var2  :最大核心线程数
var3  :超时时间(超时了没人调用就会释放)
var5  :超时时间单位
var6  :阻塞队列
var7  :线程工厂 , 一般不变
var8  :拒绝策略
  public ThreadPoolExecutor(int var1, int var2, long var3, TimeUnit var5, BlockingQueue<Runnable> var6, ThreadFactory var7, RejectedExecutionHandler var8) {
        this.ctl = new AtomicInteger(ctlOf(-536870912, 0));
        this.mainLock = new ReentrantLock();
        this.workers = new HashSet();
        this.termination = this.mainLock.newCondition();
        if (var1 >= 0 && var2 > 0 && var2 >= var1 && var3 >= 0L) {
            if (var6 != null && var7 != null && var8 != null) {
                this.acc = System.getSecurityManager() == null ? null : AccessController.getContext();
                this.corePoolSize = var1;
                this.maximumPoolSize = var2;
                this.workQueue = var6;
                this.keepAliveTime = var5.toNanos(var3);
                this.threadFactory = var7;
                this.handler = var8;
            } else {
                throw new NullPointerException();
            }
        } else {
            throw new IllegalArgumentException();
        }
    }

七大参数
在这里插入图片描述

在这里插入图片描述
var1 :核心线程数 ;一开始开启的线程数量
var2 :最大核心线程数 ;当阻塞队列满了之后,开启的剩下的核心线程
var3 :超时时间 ;剩下的核心线程数超时了没人调用就会释放
var5 :超时时间单位
var6 :阻塞队列
var7 :线程工厂
var8 :拒绝策略
在这里插入图片描述


var1 :核心线程数
var2 :最大核心线程数

选择策略
1 CPU 密集型 :电脑有多少核,最大核心线程数就写多少

  //  获取系统的CPU核数
        System.out.println(Runtime.getRuntime().availableProcessors());

2 IO 密集型 :判断程序中非常耗费IO的线程有多少个,最大核心线程数一般设为IO线程的两倍

10 四大函数式接口(必须掌握)
在这里插入图片描述
在这里插入图片描述
Function 接口使用
**加粗样式**
Predict 接口
在这里插入图片描述
实例
在这里插入图片描述

Consumer 接口
在这里插入图片描述

Supplier 接口
在这里插入图片描述
实例


        Supplier<String> stringSupplier = new Supplier<String>() {
            @Override
            public String get() {
                return Thread.currentThread().getName();
            }
        };


        Supplier<String> stringSupplier2= ()->{

            return "hello";
        };


        System.out.println(stringSupplier.get());
        System.out.println(stringSupplier2.get());

作用 : 简化编程模型

11 Stream流式计算
在这里插入图片描述

实例
在这里插入图片描述
12 ForkJoin
JDK1.7之后,并发执行,高效率,大数据量
原理:把大任务拆分成小任务
在这里插入图片描述
特点:工作窃取,当一个线程先执行完成任务之后,此线程不会等待而是会将另一个线程的任务窃取过来执行
在这里插入图片描述
在这里插入图片描述

实例

在这里插入图片描述


import java.util.concurrent.RecursiveTask;

public class Fork extends RecursiveTask<Long> {

    private Long start;
    private Long end;
    private Long temp;
    private Long sum;
    private Long mid;
    public Fork(Long start, Long end, Long temp) {
        this.start = start;
        this.end = end;
        this.temp = temp;
    }

    @Override
    protected Long compute() {
        if ((end - start) < temp){
            Long sum =0l;
            for (Long i = start; i <= end; i++) {
                sum+=i;
            }
            return sum;
        }else {
            mid = (end + start) / 2  ;
            Fork fork1 = new Fork(start, mid, temp);
            fork1.fork();  //拆分任务,将任务加入方法栈

            Fork fork2 = new Fork(mid+1, end, temp);
            fork2.fork(); //拆分任务,将任务加入方法栈

            return  fork1.join()+fork2.join();   //每个小任务的结果返回

        }

    }
}

package com.kuangsheng.Forkjoin;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;

public class ForkTest {
    private long  sum = 0l;
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ForkTest test = new ForkTest();
       //test.test1();
        test.test2();
       // test.test3();

    }



    public  void test1(){
        long l = System.currentTimeMillis();

        for (Long i = 0l; i <= 10_0000_0000; i++) {
            sum+=i;
        }
        long l1 = System.currentTimeMillis();

        System.out.println("时间"+(l1 - l)+"------------->"+"sum"+sum);

    }

    public  void test2() throws ExecutionException, InterruptedException {
        long l = System.currentTimeMillis();

        ForkJoinPool pool = new ForkJoinPool();
        Fork fork = new Fork(0l, 10_0000_0000l, 10000l);
        ForkJoinTask<Long> sub = pool.submit(fork);
         sum = sub.get();

        long l1 = System.currentTimeMillis();
        System.out.println("时间"+(l1 - l)+"------------->"+"sum"+sum);


    }

    public  void test3(){

        long l = System.currentTimeMillis();

        // Stream流 并行计算
         sum = LongStream.rangeClosed(0l, 10_0000_0000).parallel().reduce(0, Long::sum);


        long l1 = System.currentTimeMillis();

        System.out.println("时间"+(l1 - l)+"------------->"+"sum"+sum);

    }
}

13 异步回调
future: 对未来的方法进行建模
在这里插入图片描述
在这里插入图片描述
实例
1 没有返回值
在这里插入图片描述
1.1 当异步回调没有阻塞时,会按照程序顺序执行
1.2 当异步回调有阻塞时,会先对异步回调的线程发送请求,不要求立即返回结果,发送请求之后就往下执行,当需要异步回调的数据时再返回结果

2 有返回值
在这里插入图片描述
14 JMM
在这里插入图片描述
线程 工作内存 主内存

八种规定
在这里插入图片描述
在这里插入图片描述
JMM的八种交互操作(每个操作都为原子操作)
lock (锁定):作用于主内存的变量,把一个变量标识为线程独占状态
unlock (解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
read (读取):作用于主内存变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用
load (载入):作用于工作内存的变量,它把read操作从主存中变量放入工作内存中
use (使用):作用于工作内存中的变量,它把工作内存中的变量传输给执行引擎,每当虚拟机遇到一个需要使用到变量的值,就会使用到这个指令
assign (赋值):作用于工作内存中的变量,它把一个从执行引擎中接受到的值放入工作内存的变量副本中
store (存储):作用于主内存中的变量,它把一个从工作内存中一个变量的值传送到主内存中,以便后续的write使用
write  (写入):作用于主内存中的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中

**

对八种操作的规则
不允许read和load、store和write操作之一单独出现。即使用了read必须load,使用了store必须write
不允许线程丢弃他最近的assign操作,即工作变量的数据改变了之后,必须告知主存
不允许一个线程将没有assign的数据从工作内存同步回主内存
一个新的变量必须在主内存中诞生,不允许工作内存直接使用一个未被初始化的变量。就是怼变量实施use、store操作之前,必须经过assign和load操作
一个变量同一时间只有一个线程能对其进行lock。多次lock后,必须执行相同次数的unlock才能解锁
如果对一个变量进行lock操作,会清空所有工作内存中此变量的值,在执行引擎使用这个变量前,必须重新load或assign操作初始化变量的值
如果一个变量没有被lock,就不能对其进行unlock操作。也不能unlock一个被其他线程锁住的变量
对一个变量进行unlock操作之前,必须把此变量同步回主内存

可见性
在这里插入图片描述
在这里插入图片描述
不保证原子性
在这里插入图片描述
不加Lock 或者 Synchronized 关键字 怎么保证原子性
在这里插入图片描述

可以通过原子类来进行原子性实现
在这里插入图片描述
在这里插入图片描述
禁止指令重排
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
内存屏障
在这里插入图片描述
内存屏障常用与单例模式

15 单例模式

15.1 双重检测
在这里插入图片描述
15.2 静态内部类
在这里插入图片描述
15.3 枚举
在这里插入图片描述
16 CAS

在这里插入图片描述
Unsafe类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ABA问题
在这里插入图片描述
在这里插入图片描述
解决 :引入原子引用(乐观锁原理)
在这里插入图片描述
17 各种锁

17.1 公平锁:线程调度之间必须遵循先来后到


    public ReentrantLock() {
        this.sync = new ReentrantLock.NonfairSync();
    }

17.2 非公平锁:线程调度之间不必遵循先来后到,可以插队(默认:抢占式调度)

  public ReentrantLock(boolean var1) {
        this.sync = (ReentrantLock.Sync)(var1 ? new ReentrantLock.FairSync() : new ReentrantLock.NonfairSync());
    }

17.3 可重入锁
在这里插入图片描述
实例

在这里插入图片描述
synchronized
在这里插入图片描述
lock
在这里插入图片描述
17,4 自旋锁

public class Mylock {


      AtomicReference<Thread> ato = new AtomicReference<>();



      public void  mylock(){
          String name = Thread.currentThread().getName();

          System.out.println("获取锁"+name);
          while (!ato.compareAndSet(null,Thread.currentThread())){

          }
      }


      public void myunlock(){

          System.out.println("解锁"+Thread.currentThread().getName());

          ato.compareAndSet(Thread.currentThread(),null);
      }

}

Test


public class MyLockTest {
    public static void main(String[] args) throws InterruptedException {
        Mylock lock = new Mylock();


        new Thread(()->{
            lock.mylock();

            try {
                TimeUnit.SECONDS.sleep(5);
                System.out.println("T1");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
               lock.myunlock();
            }


        },"T1").start();


        TimeUnit.SECONDS.sleep(1);

        new Thread(()->{

            lock.mylock();

            try {
                TimeUnit.SECONDS.sleep(1);
                System.out.println("T2");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.myunlock();
            }

        },"T2").start();
    }

}

结果
在这里插入图片描述
17.5 死锁
在这里插入图片描述
怎么解决死锁?
1 命令 jps -l 查看当前所有的线程号
在这里插入图片描述

2 jstack 进程号 命令,查看死锁问题(堆栈信息)

在这里插入图片描述

排查问题
1 查看日志
2 查看堆栈信息

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JUC编程 的相关文章

  • war文件可以部署在任何服务器上吗?

    如果这个问题很愚蠢 请原谅我 假设我使用 Spring 框架和 MS SQL Server 数据库以及 WebSphere 应用程序服务器开发一个 J2EE Web 应用程序 我后来为此应用程序创建了一个 WAR 文件 我可以在不更改代码的
  • 表“DBNAME.hibernate_sequence”不存在

    我有一个使用 spring data jpa 的 Spring Boot 2 0 1 RELEASE 应用程序
  • 使用 IcyStreamMeta 从 SHOUTcast 获取元数据

    我正在为 Android 编写一个应用程序 从 SHOUTcast mp3 流中获取元数据 我正在使用我在网上找到的一个非常漂亮的类 我稍微修改了一下 但我仍然有两个问题 1 我必须使用 TimerTask 不断 ping 服务器来更新元数
  • 关于线程的停止

    我开发了一个代码 它将在执行时启动两个线程 public class MyThread1 extends Thread extend thread class public synchronized void run synchronize
  • 如何用Spring进行只读和读写的数据库路由

    我正在研究 Spring 中的事务路由 但我的应用程序存在运行时问题 我有两个 MySQL 数据库 一个用于读取 一个用于读 写 但是我的路由配置不起作用 当我应用只读配置时 我没有成功 这是我的配置 pom xml
  • mapFragment.getMapAsync 处的 NullPointerException

    在解决了与我的标题相关的问题后 我找不到问题的解决方案 我有一个NullPointerException at mapFragment getMapAsync 下面是我的MapActivity code package com exampl
  • 递归 - 与 Java 中不重复的数组相结合

    所以我知道如何获取组合的大小 数组大小 在我的例子中 除以所需数组子集大小的阶乘 我遇到的问题是获取组合 到目前为止 我已经阅读了 stackoverflow 上的大部分问题 但一无所获 我认为我发现的问题是我想将创建的组合子集中的元素添加
  • 字符串文字的行为令人困惑

    下面的代码中字符串文字的行为非常令人困惑 我可以理解第 1 行 第 2 行和第 3 行是true 但为什么是第 4 行false 当我打印两者的哈希码时 它们是相同的 class Hello public static void main
  • Android Studio 1.0.1 APK META-INF/DEPENDENCIES 中复制的重复文件

    我安装了 Android Studio 版本 1 0 1 并尝试将我的项目从 eclipse 导入到它 它给了我以下错误 Error Execution failed for task app packageDebug Duplicate
  • Spring - 使用 new 是一种不好的做法吗?

    正在创建对象by hand 即使用new操作员而不是注册Springbean 和使用依赖注入被认为是不好的做法吗 我的意思是 确实Spring IoC容器必须了解应用程序中的所有对象吗 如果是这样 为什么 你希望 Spring 创建 bea
  • 如何使用 Java 以编程方式登录 Facebook?

    我正在尝试编写一个可以自动登录 Facebook 的 Java 程序 到目前为止 我已经得到了以下代码 可以将主页 html 页面下载到字符串中 但不知道如何发送电子邮件和密码来登录 Facebook Java 程序还需要处理返回的 coo
  • java SWT透明复合背景

    我有复合对象 Composite composite new Composite shell SWT NONE composite setBounds new Rectangle 10 10 100 100 我如何使这个组合具有透明背景 我
  • 用 org.Json 解析 Java 中的 JSON?

    我在这方面遇到了很多麻烦 我正在尝试进行更新 并且正在使用从 url 返回此内容的 api JSON downloadUrl URL fileName Name gameVersion Version name Name projectId
  • Spring MVC - 两次提供内容

    我已经花了一周时间寻找有关如何将内容服务器到我的网页的指导 两次 因为使用 Model 或 ModelAndView 切断内容一次可以工作 但如果用户再次与页面交互 我希望它加载更多内容同一页 Java Spring 后端方法 Get 有效
  • 在 Maven Shade 插件中包含依赖项

    我正在尝试使用 Apache 的 commons lang3 创建一个可部署的 jar 但是 我的 Hadoop 所在的 AWS 集群不包含此库 因此我收到了 classNotFoundException 我想我需要手动添加该依赖项 但我在
  • 如何在pdf中导出一对一的JTable[重复]

    这个问题在这里已经有答案了 可能的重复 为什么 JTable 标题没有出现在图像中 https stackoverflow com questions 7369814 why does the jtable header not appea
  • 如何在jsf页面中嵌入java代码?

    我有 一个名为 LoginBean 的托管 bean 名为 login xhtml 的 JSF 页面 在这个 jsf 页面中 我有一个登录表单 在managebean 内部我有一个loginCheck 函数 public void logi
  • 有没有办法在坐标平面上动态绘制点之间的线?

    我正在完成一个项目 在该项目中我实现了一个暴力算法来解决凸包问题 我还需要为该算法创建视觉效果 我试图在 x 轴和 y 轴上创建一个范围从 100 100 的坐标平面 绘制完整集中的所有点 并在点之间动态绘制线条以创建凸包 例如 假设我有
  • 你在实际项目中使用过Quickcheck吗[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 快速检查 http www cs chalmers se rjmh QuickCheck 及其变体 即使有一个Java https bitbuc
  • 如何将钱兑换成零钱

    尝试将输入的数字转换为 25 美分 50 美分 10 美分和 10 分 有几个问题 public class Coins public static void main String args private int quarters di

随机推荐

  • iOS利用九切片进行切图UI不会变形

    p 1 手写代码 p p p UIImageView svRect UIImage backgroundImage UIImageimageNamed bg png backgroundImage backgroundImageresiza
  • 《机器学习》读书笔记2--线性模型

    目录 线性模型基本形式 线性回归 对数几率回归 线性判别分析 多分类学习 类别不平衡问题 ps 写在前面 本文是在参加datawhale组队学习 学习周志华老师的 机器学习 过程的学习笔记 文中出现的图片均引自 机器学习 机器学习 是初学者
  • AI绘画Stable Diffusion原理之扩散模型DDPM

    前言 传送门 stable diffusion Git 论文 stable diffusion webui Git Google Colab Notebook部署stable diffusion webui Git kaggle Noteb
  • 量化交易框架开发实践(一)

    量化交易平台指支持通过对数据进行多维度的定量分析 结合发现的特征定制策略 并能够基于历史数据对策略进行回测 最后支持实盘买卖的交易平台 从业务流上看 量化交易可以分解成 行情获取 gt 数据清洗 gt 指标计算 gt 策略开发 gt 策略回
  • RobotStudio ABB 仿真软件过期 后的处理

    首先查看当前是在试用期还是已经过期了 查看方法如下 在打开软件后的首页找到 帮助 右侧会显示当前授权状态是否为 试用 1 如果当前在试用期内 可以通过直接修改注册表方式 修改方法 找到如下位置 HKEY LOCAL MACHINE SOFT
  • 正则表达式匹配中* . c++实现

    题目描述 请实现一个函数用来匹配包括 和 的正则表达式 模式中的字符 表示任意一个字符 而 表示它前面的字符可以出现任意次 包含0次 在本题中 匹配是指字符串的所有字符匹配整个模式 例如 字符串 aaa 与模式 a a 和 ab ac a
  • QT 怎么导入qss文件?

    方式一 比较常见的方法 QFile file qss psblack css if file open QFile ReadOnly QString qss QLatin1String file readAll qApp gt setSty
  • 提高电脑寿命的维护技巧与方法分享

    在维护电脑运行方面 我有一些自己觉得非常有用的技巧和方法 下面我将分享一些我常用的维护技巧 并解释为什么我会选择这样做以及这样做的好处 首先 我经常清理我的电脑内部的灰尘 电脑内部的灰尘会影响散热效果 导致电脑发热严重甚至性能下降 因此 定
  • Google Colab 上部署 Stable Diffusion Web UI

    什么是 Stable Diffusion Web UI Colab Stable Diffusion 是 Stability AI 推出的一个基于深度学习技术文字生成图片AI模型 Stable Diffusion Web UI 是一个强大好
  • [技术经理]03 到底是能力重要,还是态度重要?

    对于一个技术团队而言 团队里面的人员是最最重要的财富 人员的招聘和人员的管理是技术经理最重要的工作之一 但是 事实也是 没有什么问题比人的问题更难处理的了 我先讲两个发生在我们团队里面的事件 今年上半年的时候 我们团队同时入职了两名前端开发
  • C语言中sizeof()和strlen()的区别

    sizeof 一 sizeof的基本概念 sizeof操作符以字节形式给出了其操作数的存储大小 操作数可以是一个表达式或括在括号 内的类型名 操作数的存储大小由操作数的类型决定 二 使用方法 1 用于数据类型 sizeof使用形式 size
  • UBUNTU16.04命令行安装PCL1.7(亲测有效)

    安装PCL点云库 最开始是按照先安装相关依赖 然后github上clone PCL相关版本包的形式安装的 编译遇到了很多问题 结果最后安装完成 但却无法运行例程 难过 又尝试了命令行的形式 命令行的形式直观简单 可安装编译好的点云库 PCL
  • [Python人工智能] 九.gensim词向量Word2Vec安装及《庆余年》中文短文本相似度计算

    从本专栏开始 作者正式开始研究Python深度学习 神经网络及人工智能相关知识 前一篇详细讲解了卷积神经网络CNN原理 并通过TensorFlow编写CNN实现了MNIST分类学习案例 本篇文章将分享gensim词向量Word2Vec安装
  • 时频分析常用工具:STFT短时傅里叶变换 & 小波变化

    文章目录 1 傅里叶变换的局限性 2 STFT 3 小波变换 参考 时频分析之STFT 短时傅里叶变换的原理与实现 形象易懂讲解算法I 小波变换 https www zhihu com question 58814934 1 傅里叶变换的局
  • MSCOCO数据集格式转化成VOC数据集格式

    MSCOCO数据集格式转化成VOC数据集格式 转载请注明原出处 http blog csdn net ouyangfushu article details 79543575 作者 SyGoing QQ 2446799425 SSD目标检测
  • CUDA(C)和PyCUDA(Python) GPU加速OpenCV视觉

    CUDA 本节介绍一个简单的加法程序 该程序在设备上执行两个变量的加法 虽然它没有利用设备的任何数据并行性 但它对于演示 CUDA C 的重要编程概念非常有用 首先 我们将看到如何编写一个用于添加两个变量的内核函数 内核函数的代码如下所示
  • 面试之JVM类的生命周期

    按照Java虚拟机规范 从class文件到加载到内存中的类 到类卸载出内存为止 它的整个生命周期包括如下7个阶段 加载 类的加载指的是将类的 class文件中的二进制数据读取到内存中 存放在运行时数据区的方法去中 在加载的过程中 jvm需要
  • FFMPEG之H264获取NALU并且解析其RBSP类型03

    FFMPEG之H264获取NALU并且解析其RBSP类型03 前言 FFMPEG之H264理论篇 理论的就不多讲了 可以参考上面那篇文章 下面将给出两种版本 一种是我自己的 用C 方法实现 另一种是雷神版本的 基本是纯C语言 区别是我多了一
  • MySQL 排序时如何把0放最后, 其它按照从小到大排序

    问题描述 MySQL 在排序时 如何从小到大排序 并将0排在最后面 如图 解决办法 利用CASE THEN来处理 原理是将sort等于0的转为比较大的数值放到了最后 其实也是遵循了 sort ASC 的原则 SELECT FROM bann
  • JUC编程

    1 JUC JUC就是java util concurrent工具包的简称 这是一个处理线程的工具包 JDK 1 5开始出现的 1 传统的synchronized public class Synchronized public stati