JUC(java中的多线程)

2023-10-27

JUC

介绍

JUC是jdk中java.util.concurrent包的简称,该包提供了并发编程中常用的工具类。概括地说,JUC的就 是java并发编程工具包。

目前juc泛指Java多线程开发技术

线程和进程

进程:运行中的程序,一个进程包括很多线程

线程:进程中的(运行中的)单一串行程序片段

线程的创建方式

  1. 继承Thread

package org.juc.线程创建的几种方式;
​
import lombok.extern.slf4j.Slf4j;
​
@Slf4j
public class One extends Thread{
    @Override
    public void run() {
        for(int i=1;i<=1000;i++){
            log.debug("----->{}",i);
        }
    }
    public static void main(String[] args) {
        Thread t = new One();
        t.start();
    }
}

2.使用Runnable接口结合Thread类

package org.juc.线程创建的几种方式;
​
import lombok.extern.slf4j.Slf4j;
​
@Slf4j
public class Two implements Runnable{
​
    @Override
    public void run() {
        for(int i=1;i<=1000;i++){
            log.debug("----->{}",i);
        }
    }
​
    public static void main(String[] args) {
        Two two = new Two();
        Thread t = new Thread(two);
        t.start();
    }
}

第二种方式 进阶1:内部类的方法

Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 1;i <= 1000;i++){
                    log.debug("----->()",this.getName(),i);
                }
            }
        };

第二种方式 进阶2:lamada表达式

 Thread t2 = new Thread(()->{
            for (int i = 1;i <= 1000;i++){
                log.debug("----->()",Thread.currentThread().getName(),i);
            }
        },"T2");

3.利用Callable接口、FutureTast类结合Thread(有返回值时用这个)(不常用)

package org.juc.线程创建的几种方式;
​
import lombok.extern.slf4j.Slf4j;
​
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
​
@Slf4j
public class Three {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Integer> callable = new Callable() {
            @Override
            public Object call() throws Exception {
                TimeUnit.SECONDS.sleep(5);
                return 100;
            }
        };
        FutureTask<Integer> futureTask = new FutureTask(callable);
        Thread t1 = new Thread(futureTask);
        t1.start();
        //get方法是阻塞方法,一直到内部的call方法执行完毕才返回
        Integer k = futureTask.get();
        log.debug("{}",k);
        System.out.println(k);
    }
}

4.利用线程池

线程的状态:

  • 新建:刚刚new出来的线程对象

  • 就绪:已调用start,但尚未运行,但正在积极竞争cpu

  • 运行:正在运行

  • 阻塞:不竞争cpu(即使cpu空闲),阻塞状态结束进入就绪状态

  • 死亡:线程运行结束

阻塞状态不竞争cpu,阻塞状态结束后才竞争cpu,就绪状态正在竞争cpu ​ 阻塞已经启动过了,就绪还未启动,阻塞结束后进行就绪

与线程相关的API

Thread.yield() 致使当前线程进入就绪状态(也叫做让步方法,由运行状态变成就绪状态,让出cpu的使用权)

Thread.sleep() 致使当前线程进入阻塞状态一段时间

join方法(线程实例方法)致使当前线程进入阻塞状态,等待被调用join方法的线程执行完毕后,再接着执行。如果在当前线程中调用另外一个线程的join方法,则就会等待另外一个线程(即使另外一个线程就绪或阻塞)执行完毕,才会执行。

package org.juc;
​
import lombok.extern.slf4j.Slf4j;
​
@Slf4j
public class Test02 {
    public static void main(String[] args) {
        Thread t1 = new Thread(()->{
            for (int i = 1;i <= 1000;i++){
                log.debug("{}----->{}",Thread.currentThread().getName(),i);
            }
        },"T1");
        Thread t2 = new Thread(()->{
            for (int i = 1;i <= 1000;i++){
                log.debug("{}----->{}",Thread.currentThread().getName(),i);
                if (i == 200){
                    try {
                        t1.join();//等待t1执行完毕
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"T2");
        t1.start();
        t2.start();
    }
}

wait方法(Object实例的方法)致使当前线程阻塞,需要其它线程调用notify或者notifyAll方法。

sleep是睡眠一段时间 
wait是进入阻塞,没有notify方法不会继续执行

线程的优先级

多个运行态的线程,其中优先级较高的,竞争上cpu的概率较高。

优先级:1~10(越大优先级越高)

  • 优先级较高的线程被cpu调用的概率更高

通过线程的setPriority设置线程的优先级

线程中断interrupt(中断)

1.对于不在阻塞状态的线程,interrupt方法仅仅修改中断状态为true,不影响线程的执行

2.对于阻塞的线程,interrupt方法将终止阻塞并抛出InterruptedException,同时恢复中断状态为 false(isInterrupted())。

对中断线程怎么处理由开发者决定,根据isinterrupted来进判断是否处于中断状态

package org.juc.线程中断;
​
import lombok.extern.slf4j.Slf4j;
​
@Slf4j
public class Test01 {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(()->{
            for (int i = 1;i <= 1000;i++){
                log.debug("----->()",i,Thread.currentThread().isInterrupted());
                if (Thread.currentThread().isInterrupted()){
                    //假如线程处于阻塞状态,则return
                    return;
                }
                Thread.yield();
            }
        },"T2");
        t1.start();
        Thread.sleep(10);
        t1.interrupt();  //向被调用的线程发送中断信号
        // 线程可以收到中断信号,但是收到中断信号的逻辑由开发者决定
    }
}

守护线程

  • 垃圾回收线程是一个守护线程

守护线程是为其他线程服务的线程,随着其他线程的结束而结束

package org.juc;
​
public class Test04 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            while (true){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("我是守护线程。。。");
            }
        });
        t.setDaemon(true);
        t.start();
        Thread.sleep(1000);
    }
}

输出结果:守护线程运行两次后结束

 

如果不设置t为守护线程,则这个线程会一直运行,不会终止

互斥

synchronized是同步代码块的简洁写法 
同步实例方法:以this对象为锁,以整个方法体为同步代码块 
同步静态方法:以所属类的元对象为锁,以整个方法体为同步代码块

变量的线程安全问题

  1. 基本类型的局部变量和变量所引用对象作用范围不超出局部范围的引用类型变量没有线程安全问题。

  2. 属性(类的实例属性和静态属性)需要考虑线程安全问题

  3. 变量所引用对象作用范围超出局部范围的引用类型变量需要考虑线程安全问题

StringBuffer是线程安全的,StringBuilder是线程不安全的,StringBuilder效率比StringBuffer效率高,加锁导致效率降低

线程的同步-协作(生产者和消费者问题)

场景:

一个面包柜只能容纳5个面包,面包师傅每天拷100个面包放入面包柜,店员每天从面包柜中取 100个面包销售。

操作:

师傅每放入一个面包就通知(notify)店员可以取了,如果师傅发现柜子满了,则等待(wait)直到被唤醒(通知)

店员没取出一个面包就通知师傅可以放了,如果店员发现柜子空了,则等待中直到被唤醒(通知)

满了就让师傅等待,空了就让店员等待

java.lang.Object 提供了三个方法:

wait()只能在同步代码中调用,而且只能通过锁对象调用,使当前线程基于所在代码锁等待。

notify() 只能在同步代码中调用,而且只能通过锁对象调用,唤醒【基于当前线程所在代码锁等待的】线程中的一个

notifyAll()只能在同步代码中调用,而且只能通过锁对象调用,唤醒【基于当前线程所在代码锁等待的】所有线程

实现代码:

柜子类

package org.juc.线程协作.线程协作plus;
​
import lombok.extern.slf4j.Slf4j;
​
@Slf4j
public class Guizi {
    private int cap; //容量
    private int size;//数量
​
    public Guizi(int cap) {
        this.cap = cap;
        this.size = 0;
    }
    public boolean isFull(){
        return size == cap;
    }
    public boolean isEmpty(){
        return size == 0;
    }
    public synchronized void add (){
        while (this.isFull()){
            try {
                log.debug("柜满,等待中。。。");
                this.wait();
                log.debug("有空位,被唤醒。。。");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        size++;
        log.debug("放入一个面包,面包数为:{}",size);
        this.notifyAll();
​
    }
    public synchronized void remove (){
        while (this.isEmpty()){
            try {
                log.debug("柜空,等待中。。。");
                this.wait();
                log.debug("有面包,被唤醒。。。");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        size--;
        log.debug("取出一个面包,面包数为:{}",size);
        this.notifyAll();
    }
}
​

启动类

package org.juc.线程协作.线程协作plus;
​
import lombok.extern.slf4j.Slf4j;
​
@Slf4j
public class Test01 {
    public static void main(String[] args) {
        Guizi guizi = new Guizi(5);
        for (int k=0;k<7;k++) {
            new Thread(() -> {
                for (int i = 0; i < 100; i++) {
                    guizi.add();
                    Thread.yield();
                }
            }, "面包师"+k).start();
            new Thread(() -> {
                for (int i = 0; i < 100; i++) {
​
                    guizi.remove();
                    Thread.yield();
                }
            }, "店员"+k).start();
        }
    }
}

synchronized锁升级

偏向锁->轻量级锁->重量级锁

偏向锁:仅有一个线程访问,当有另一个线程访问时升级为轻量级锁

轻量级锁:有多个线程不同时间访问,当多个线程同时访问时产生锁自选

锁的自旋:当一个线程持有锁,另一个线程访问同步代码块时并不阻塞,而是进入循环,等待获取到同步代码块的锁后执行,循环次数大于jvm设置的上限之后升级为重量级锁。(处于运行状态,还在占用cpu,减少在运行态和阻塞态之间切换的消耗)

重量级锁:当锁自旋次数大于jvm设置的上限之后,还没有获得锁的线程进入阻塞状态。

JAVA内存模型(JMM)

多线程把内存分为主内存和工作内存,工作内存是线程独有的

当一个线程从非运行状态变成运行状态时会从主存中更新工作内存的数据

当一个线程拿到锁之后会从主存拿取数据,释放锁的时候将数据向主存回传

线程只要遇到锁,就会从主存中更新工作内存

注:被volatile修饰的变量,主存内的值改变后,立即通知各工作内存从主存中重新读取值。

JMM三大特性

  • 原子性-如何保证指令不会受到线程上下文切换的影响。线程上下文切换主要指运行态和阻塞态之间的转换,这个切换消耗成本较大。

  • 可见性-如何保证指令不受cpu缓存的影响 (工作内存与主存里的值不一样)

  • 有序性-如何保证指令不受cpu指令优化的影响(cpu进行优化时可能会进行指令重排)

synchronized可以保证原子性(锁升级),可见性

volatile可以保证可见性,禁止指令重排(有序性),但不保证原子性(适合一个线程写,多个线程读的情况)

CAS(无锁技术)

CAS即比较并设置,是一种无锁的、非阻塞的线程并发安全技术。

CAS操作:设置新值时,首先将数据的当前值和预期原值进行比较,如果一致则更新为新值,否则 不更新。

CAS和volatile结合实现了安全的原子性并发 在Java中提供的原子数据类型就是这样做的。

线程池ThreadToolExecutor

少量线程对应大量任务,节约资源,效率较高

核心线程

救急线程

阻塞队列

公平锁和非公平锁

公平锁:按照请求锁的顺序依次获得锁,好处是每个线程都有获得锁的机会,效率低一些。

一开始时是线程一处于第一位,线程一执行完之后释放锁,再重新去排队

package org.juc.公平锁和非公平锁;
​
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
​
public class 公平锁 {
    public static void main(String[] args) {
        Task task = new Task();
        Thread t1 = new Thread(task,"线程一");
        Thread t2 = new Thread(task,"线程二");
        Thread t3 = new Thread(task,"线程三");
        t1.start();
        t2.start();
        t3.start();
    }
}
​
class Task implements Runnable {
    Lock l = new ReentrantLock(true);//创建一个公平锁
​
    @Override
    public void run() {
        while (true) {
            l.lock();
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                l.unlock();
            }
        }
    }
}

非公平锁:不按照请求顺序获得锁,而是随机顺序获得锁,好处是效率较高,但是有的线程没有获得锁的机会(锁饥饿)。

synchronized是非公平锁

package org.juc.公平锁和非公平锁;
​
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
​
public class 非公平锁 {
    public static void main(String[] args) {
        Task1 task1 = new Task1();
        Thread t1 = new Thread(task1,"线程一");
        Thread t2 = new Thread(task1,"线程二");
        Thread t3 = new Thread(task1,"线程三");
        t1.start();
        t2.start();
        t3.start();
    }
}
​
class Task1 implements Runnable {
    Lock l = new ReentrantLock(false);//创建一个非公平锁
​
    @Override
    public void run() {
        while (true) {
            l.lock();
            try {
                Thread.sleep(1000);//每一秒输出一次当前正在执行线程的名字
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                l.unlock();
            }
        }
    }
}

Lock接口

有三个实现类,分别是可重入锁ReentrantLock、读锁ReadLock、写锁writeLock

可重入锁(ReentrantLock)

本线程已经有这个锁之后再获得一次这个锁,获得几次就得释放几次。(Synchronized也是可重入锁。)

可重入锁ReentrantLock(默认非公平锁,可以设置为公平锁或非公平锁)可以完全替代synchronized关键字,并且在扩展功能上也更加强大,而且在使用上也更加灵活。

synchronized与ReentrantLock的区别:

synchronized:无论是否发生异常都自动释放 
ReentrantLock等:释放需要手动通过代码释放

读写锁(ReadWriteLock接口)

  • 读-读不阻塞

  • 读-写阻塞

  • 写-写阻塞

创建方式

ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();//读锁
Lock writeLock = lock.writeLock();//写锁

Condition接口

在Lock接口的实现类里,属于Object的wait和notify就不能使用了,jdk为我们提供了一个新的方法,即通过Conition接口的await()方法和signal() 方法和signalAll()方法.

创建方式

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

线程协作(读写锁版本)

柜子类

package org.juc.线程协作.读写锁版本;
​
import lombok.extern.slf4j.Slf4j;
​
import java.util.Locale;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
​
@Slf4j
public class Guizi {
    private int cap; //容量
    private int size;//数量
​
    ReadWriteLock lock = new ReentrantReadWriteLock();
    Lock readLock = lock.readLock();
    Lock writeLock = lock.writeLock();
    Condition condition = writeLock.newCondition();
​
    public Guizi(int cap) {
        this.cap = cap;
        this.size = 0;
    }
​
    public boolean isFull() {
        readLock.lock();
        try {
            return size == cap;
        } finally {
            readLock.unlock();
        }
    }
​
    public boolean isEmpty() {
        readLock.lock();
        try {
            return size == 0;
        } finally {
            readLock.unlock();
        }
    }
​
    public void add() {
        writeLock.lock();
        try {
            while (this.isFull()) {
                try {
                    log.debug("柜满,等待中。。。");
                    condition.await();
                    log.debug("有空位,被唤醒。。。");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            size++;
            log.debug("放入一个面包,面包数为:{}", size);
            condition.signalAll();
        } finally {
            writeLock.unlock();
        }
​
    }
​
    public void remove() {
        writeLock.lock();
        try {
            while (this.isEmpty()) {
                try {
                    log.debug("柜空,等待中。。。");
                    condition.await();
                    log.debug("有面包,被唤醒。。。");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            size--;
            log.debug("取出一个面包,面包数为:{}", size);
            condition.signalAll();
        } finally {
            writeLock.unlock();
        }
    }
}

启动类

package org.juc.线程协作.读写锁版本;
​
import lombok.extern.slf4j.Slf4j;
​
@Slf4j
public class Test01 {
    public static void main(String[] args) {
        Guizi guizi = new Guizi(5);
        for (int k=0;k<7;k++) {
            new Thread(() -> {
                for (int i = 0; i < 100; i++) {
                    guizi.add();
                    try {
                        Thread.sleep(1); //让它阻塞,释放对cpu的使用权
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "面包师"+k).start();
            new Thread(() -> {
                for (int i = 0; i < 100; i++) {
​
                    guizi.remove();
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "店员"+k).start();
        }
    }
}

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

JUC(java中的多线程) 的相关文章

  • 使用 Intellij Idea 和 gradle 在应用程序引擎上调试 localhost

    我正在使用 IntelliJ 社区添加并使用 Gradle 构建应用程序引擎标准环境应用程序 在迁移到 IntelliJ 和端点框架之前 我使用的是 Android Studio 我无法调试我的本地主机 我添加了 jvmFlags 如下所述
  • Netbeans 8.1 Gnome 3 GTK+ UI 字体和选项卡高度

    我刚刚在运行 GNOME 3 桌面的 Ubuntu 16 04 上安装了 NetBeans 8 1 如果可能的话 我想继续使用 IDE 的 GTK 外观和感觉 但 UI 上的字体 尤其是选项卡中的字体 太小且重叠 我尝试添加 fontsiz
  • 为什么即使我的哈希码值相同,“==”也会返回 false

    我写了一个像这样的课程 public class HashCodeImpl public int hashCode return 1 public static void main String args TODO Auto generat
  • 如何调试“com.android.okhttp”

    在android kitkat中 URLConnection的实现已经被OkHttp取代 如何调试呢 OkHttp 位于此目录中 external okhttp android main java com squareup okhttp 当
  • 如何在 JPQL 或 HQL 中进行限制查询?

    在 Hibernate 3 中 有没有办法在 HQL 中执行相当于以下 MySQL 限制的操作 select from a table order by a table column desc limit 0 20 如果可能的话 我不想使用
  • 如何在 Java 中向时间戳添加/减去时区偏移量?

    我正在使用 JDK 8 并且玩过ZonedDateTime and Timestamp很多 但我仍然无法解决我面临的问题 假设我得到了格式化的Timestamp在格林威治标准时间 UTC 我的服务器位于某处 假设它设置为Asia Calcu
  • Android中如何使用JNI获取设备ID?

    我想从 c 获取 IMEIJNI 我使用下面的代码 但是遇到了未能获取的错误cls 它总是返回NULL 我检查了环境和上下文 它们都没有问题 为什么我不能得到Context班级 我在网上搜索了一下 有人说我们应该使用java lang Ob
  • 提供节点名或服务名,或未知 Java

    最近我尝试运行我的 Java 项目 每当我运行它并将其打开到我得到的服务器地址时 Unable to determine host name java net UnknownHostException Caused by java net
  • 如何仅从 Firestore 获取最新更新的数据?

    在 Firestore 上发现任何更改时始终获取整个文档 如何只获取最近更新的数据 这是我的数据 我需要在第一次加载时在聊天中按对象顺序 例如 2018 09 17 30 40 msg和sendby 并且如果数据更新则仅获取新的msg和se
  • 如何在 ant 中为 junit 测试设置 file.encoding?

    我还没有完全完成file encoding 和 ant https stackoverflow com questions 1339352 how do i set dfile encoding within ants build xml
  • 如何使用 JMagick 转换色彩空间?

    如何使用 JMagick API 转换色彩空间 例如 CMYK gt RGB 和 RGB gt CMYK None
  • Java继承,扩展类如何影响实际类

    我正在查看 Sun 认证学习指南 其中有一段描述了最终修饰符 它说 如果程序员可以自由地扩展我们所知的 String 类文明 它可能会崩溃 他什么意思 如果可以扩展 String 类 我是否不会有一个名为 MyString 的类继承所有 S
  • 蓝牙发送和接收文本数据

    我是 Android 开发新手 我想制作一个使用蓝牙发送和接收文本的应用程序 我得到了有关发送文本的所有内容逻辑工作 但是当我尝试在手机中测试它时 我看不到界面 这是Main Activity Code import android sup
  • 如何将 HTML 链接放入电子邮件正文中?

    我有一个可以发送邮件的应用程序 用 Java 实现 我想在邮件中放置一个 HTML 链接 但该链接显示为普通字母 而不是 HTML 链接 我怎样才能将 HTML 链接放入字符串中 我需要特殊字符吗 太感谢了 Update 大家好你们好 感谢
  • Java Swing - 如何禁用 JPanel?

    我有一些JComponents on a JPanel我想在按下 开始 按钮时禁用所有这些组件 目前 我通过以下方式显式禁用所有组件 component1 setEnabled false 但是有什么办法可以一次性禁用所有组件吗 我尝试禁用
  • 部署 .war 时出现 Glassfish 服务器错误:部署期间发生错误:准备应用程序时出现异常:资源无效

    我正在使用以下内容 NetBeans IDE 7 3 内部版本 201306052037 爪哇 1 7 0 17 Java HotSpot TM 64 位服务器虚拟机 23 7 b01 NetBeans 集成 GlassFish Serve
  • 将 JScrollPane 添加到 JFrame

    我有一个关于向 Java 框架添加组件的问题 我有一个带有两个按钮的 JPanel 和一个添加了 JTable 的 JScrollPane 我想将这两个添加到 JFrame 中 我可以将 JPanel 添加到 JFrame 或将 JScro
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • Java RMI - 客户端超时

    我正在使用 Java RMI 构建分布式系统 它必须支持服务器丢失 如果我的客户端使用 RMI 连接到服务器 如果该服务器出现故障 例如电缆问题 我的客户端应该会收到异常 以便它可以连接到其他服务器 但是当服务器出现故障时 我的客户端什么也
  • MiniDFSCluster UnsatisfiedLinkError org.apache.hadoop.io.nativeio.NativeIO$Windows.access0

    做时 new MiniDFSCluster Builder config build 我得到这个异常 java lang UnsatisfiedLinkError org apache hadoop io nativeio NativeIO

随机推荐

  • js 根据身份证号或者出生日期,计算年龄

    const idCard 110101191507288317 先计算出出生日期 var re eighteen d 6 d 4 d 2 d 2 d 3 0 9 X var arr data idCard match re eighteen
  • 憨批的语义分割重制版1——Keras 搭建自己的PSPnet语义分割平台

    憨批的语义分割重制版1 Keras 搭建自己的PSPnet语义分割平台 注意事项 学习前言 什么是PSPNet模型 代码下载 PSPNet实现思路 一 预测部分 1 主干网络介绍 2 加强特征提取结构 3 利用特征获得预测结果 二 训练部分
  • 期货开户不同的资金可以做哪些品种

    现在经济比较好 大家兜里也都有些闲钱 以前都是把闲钱放到银行 可是银行利息低 现在物价这么高 都跑不赢通货膨胀 就想到炒股 炒期货 炒基金 都想要在这个期货市场上赚点意外之财 都听说炒期货交易非常不错 但是 不知道期货交易需要多少资金门槛
  • Java 4-4、Log日志配置

    Log日志配置 均在application dev properties配置 一 springboot自带的 日志打印 执行sql打印开关 logging level com a2j mapper debug 日志备份 存放的文件名 log
  • Jenkins+maven+findbugs对java代码进行静态代码分析

    一 POM xml的修改 1 在build里面配置 代码如下
  • c++工厂模式

    以下是我自己学习设计模式的思考总结 简单工厂模式 简单工厂模式是工厂模式中最简单的一种 他可以用比较简单的方式隐藏创建对象的细节 一般只需要告诉工厂类所需要的类型 工厂类就会返回需要的产品类 但客户端看到的只是产品的抽象对象 无需关心到底是
  • 微信小程序-wxParse插件的使用

    wxParse是一个微信小程序富文本解析组件 现在小程序里面自带了一个
  • golang中定时器ticker

    package main import fmt time func main t time Now Unix 秒时间戳 fmt Println 秒时间戳 t t time Now UnixMilli 毫秒 fmt Println 毫秒时间戳
  • TypeError: can‘t unbox heterogeneous list: int64 = float64

    TypeError can t unbox heterogeneous list int64 float64 使用 numba 加速程序的时候 可能会报这个错误 一般的原因是因为某个list 里面的元素存在多种数据类型 比如同时存在 int
  • C/C++中判断某一文件或目录是否存在

    C C 中判断某一文件或目录是否存在 1 C 很简单的一种办法 include lt iostream gt include lt fstream gt using namespace std define FILENAME stat da
  • stm32 DMA2D使用中断LVGL,提高LVGL帧率

    我看了很多DMA2D教程都是用阻塞方式来刷新屏 这样就消耗了性能 相当于没用DMA 所以我使用DMA2D中断来传输数据 测试平台 stm32f429 正点原子7寸1024x600液晶屏 45MHZ刷新率 LVGL 公有条件 LTDC刷新率4
  • 2023年清洁能源与智能电网国际会议(CCESG 2023)

    会议简介 Brief Introduction 2023年清洁能源与智能电网国际会议 CCESG 2023 会议时间 2023年 召开地点 中国南宁 大会官网 CCESG 2023 2023 International Joint Conf
  • T+0交易与结算

    T 0交易 T 0交易制度 是指 投资者当天卖出股票获得的资金在当天就可以买入股票 当天买入的股票在当天就可以卖出 的一种证券交易机制 实际上 T 0交易是我国证券市场参与者之间的一种通俗叫法 正式名称为 当日回转交易 在 上海证券交易所交
  • ssm109基于jsp的网上手机商城+jsp

    文章仅展示部分内容 详细的毕设论文和演示视频可以私信我的扣扣 毕业设计 论文 网上手机商城 学 院 专 业 班 级 学 号 用户姓名 指导教师 完成日期 年 月 日 摘 要 随着科学技术的飞速发展 各行各业都在努力与现代先进技术接轨 通过科
  • 封神台——BurpSuite入门(改包、爆破)

    点击传送门进来看到的就是一个很简陋的网站 我们来到一个网站就先注册一下 感受一下全面的服务 一个假网做的还挺完备 点击一个产品 看到他的设计如此之烂 什么也没有居然要价5400 很多购物网站都存在着支付漏洞 于是我们抓个包试试看 首先打开B
  • 毕业设计-基于计算机视觉技术的指针式仪表智能识别系统

    目录 前言 课题背景和意义 实现技术思路 一 方法设计 二 表盘定位方法 二 表盘定位方法 三 CTPN CRNN网络读取数值与位置 四 示数识别模块 五 实验与分析 六 总结 实现效果图样例 最后 前言 大四是整个大学期间最忙碌的时光 一
  • 异步查询如何做节流(只查询时间段最后一次)

    要实现异步查询的节流 只查询时间范围内的最后一次 可以使用一个定时器来延迟执行查询操作 并在每次触发查询时取消之前的定时器 这样 只有在一定时间内没有新的查询请求时 才会执行最后一次查询 以下是一个示例的JavaScript代码实现 let
  • msq安装及其密码修改

    mysql 8 0安装与使用 不需要配置my ini 1 去官网下载mysql 8 0 https dev mysql com downloads mysql 8 0 html 解压版mysql 2 直接解压 配置path路径 配置系统环境
  • 常用邮箱服务器(SMTP,POP3)地址

    常用邮箱SMTP服务器地址大全 谷歌邮箱 google com POP3服务器地址 pop gmail com SSL启用端口 995 SMTP服务器地址 smtp gmail com SSL启用端口 587 新浪邮箱 sina com P
  • JUC(java中的多线程)

    JUC 介绍 JUC是jdk中java util concurrent包的简称 该包提供了并发编程中常用的工具类 概括地说 JUC的就 是java并发编程工具包 目前juc泛指Java多线程开发技术 线程和进程 进程 运行中的程序 一个进程