与线程相关的知识点

ABB机器人RAPID编程—外部IO信号触发中断 1.中断程序TRAP     中断程序拥有更高优先级,当中断触发条件满足时,程序指针即从当前运行处跳转至中断服务程序,中断服务程序运行结束后方才继续执行中断跳转前的指令。 2.中断数据intnum    中断数据用于将中断触发条件与中断服务程序相关联的中间数据    必须为全局变量,且存储类型为变量 3.中断指令    IDelete intno1; 阅读详情

与线程相关的知识点

文章参考1: https://blog.youkuaiyun.com/boker_han/article/details/82918881
文章参考2: https://blog.youkuaiyun.com/sinat_33087001/article/category/9270706
文章参考3: https://mp.weixin.qq.com/s/feZocJfW4CRoODISxlBaCQ
https://mp.weixin.qq.com/s/rkl916p8RIErGn58DNcihw
公众号的老哥:java进阶架构师

多线程

并发编程的知识比较零散,相关度很低,总是给人一种感觉,“学习了很多相关知识,可还是没搞懂是怎么回事”。那么,接下来就由我跟你一起来理一理Java并发编程的脉络。
1.并发理论:并发编程要解决的三大问题;介绍可见性与有序性问题的根源重排序;学习Java内存模型(JMM),理解JMM如何解决这些问题以实现并发编程的。
2.并发关键字:深入volatile、synchronized、final关键字的作用,都解决了什么问题,以及其实现原理。
3.并发基础:并发编程中用到的一些基本概念,如:死锁、饥饿与公平等;线程的创建、运行、调度。
4.CAS原子操作:并发编程的基础与核心CAS的实现原理,以及Java中的CAS原子操作。
5.Lock体系:JDK的Lock对于synchronized有哪些优势;Lock如何通过AQS与LockSupport工具实现的;Lock的使用。
6.并发工具:介绍java.util.concurrent包下提供的并发工具倒计时器CountDownLatch、循环栅栏CyclicBarrier、资源访问控制Semaphore、数据交换Exchanger的用法,并深入分析实现原理。
7.并发容器:介绍java.util.concurrent包下提供的并发容器ConcurrentHashMap、CopyOnWriteArrayList、ConcurrentLinkedQueue、ThreadLocal、及阻塞队列的用法,并深入分析实现原理。
8.线程池(Executor体系):介绍线程池ThreadPoolExecutor和ScheduledThreadPoolExecutor的用法,分析线程池执行流程和原理。

说明

多线程不是为了提高执行速度,而是提高应用程序的使用率。
线程和线程共享 堆内存和方法区内存”,栈内存是独立的,一个线程一个栈。
可以给现实世界中的人一种错觉:感觉多个线程在同时并发执行。
多线程:指的是这个程序(一个进程)运行时产生了不止一个线程

一.常见的概念

并行与并发:
  1. 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
  2. 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。
线程安全:

经常用来描绘一段代码。指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。反过来,线程不安全就意味着线程的调度顺序会影响最终结果.

共享和可变

要编写线程安全的代码,其核心在于对共享的和可变的状态进行访问。

“共享”就意味着变量可以被多个线程同时访问。我们知道系统中的资源是有限的,不同的线程对资源都是具有着同等的使用权。有限、公平就意味着竞争,竞争就有可能会引发线程问题。

“可变”是指变量的值在其生命周期内是可以发生改变的。“可变”对应的是“不可变”。我们知道不可变的对象一定是线程安全的,并且永远也不需要额外的同步(因为一个不可变的对象只要构建正确,其外部可见状态永远都不会发生改变)。所以“可变”意味着存在线程不安全的风险。

线程与进程的区别归纳

a.地址空间和其它资源:进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
b.通信:进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
c.调度和切换:线程上下文切换比进程上下文切换要快得多。
d.在多线程OS中,进程不是一个可执行的实体。

信号量与锁

信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在 哪里)。而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候锁和信号量会同时使用的

也就是说,信号量不一定是锁定某一个资源,而是流程上的概念,比如:**有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务 并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。**而线程互斥量则是“锁住某一资源”的概念,在锁定期间内,其他线程无法对被保护的数据进 行操作。在有些情况下两者可以互换。

线程的基本性质

原子性

原子是世界上最小的单位,具有不可分割性。在我们编程的世界里,某个操作如果不可分割我们就称之为该操作具有原子性。例如:i = 0,这个操作是不可分割的,所以该操作具有原子性。如果某个操作可以分割,那么该操作就不具备原子性,例如i++。非原子操作都存在线程安全问题,这个时候我们需要使用同步机制来保证这些操作变成原子操作,来确保线程安全。
为什么会有原子性问题?

线程是CPU调度的基本单位。CPU会根据不同的调度算法进行线程调度,将时间片分派给线程。当一个线程获得时间片之后开始执行,在时间片耗尽之后,就会失去CPU使用权。多线程场景下,由于时间片在线程间轮换,就会发生原子性问题。
如:对于一段代码,一个线程还没执行完这段代码但是时间片耗尽,在等待CPU分配时间片,此时其他线程可以获取执行这段代码的时间片来执行这段代码,导致多个线程同时执行同一段代码,也就是原子性问题。
线程切换带来原子性问题。
在这里插入图片描述
可见性

线程可见性是指线程之间的可见性**,即一个线程对状态的修改对另一个线程是可见的**,也就是一个线程修改的结果,另外一个线程立马就知道了。比如volitile修饰的变量,就具备可见性。
为什么会有可见性问题?

对于如今的多核处理器,每颗CPU都有自己的缓存,而缓存仅仅对它所在的处理器可见,CPU缓存与内存的数据不容易保证一致。
为了避免处理器停顿下来等待向内存写入数据而产生的延迟,处理器使用写缓冲区来临时保存向内存写入的数据。写缓冲区合并对同一内存地址的多次写,并以批处理的方式刷新,也就是说写缓冲区不会即时将数据刷新到主内存中。
缓存不能及时刷新导致了可见性问题。
在这里插入图片描述
补充一下多核CPU

多核CPU即多个CPU组成,这些CPU集成在一个芯片里,可以通过内部总线来交互数据,共享数据,这些CPU中分配出一个独立的核执行操作系统,每个核都有自己的寄存器,alu运算单元等(这些都是封装在cpu内部的),但是一级二级缓存是共享的,这些CPU通过总线来交互数据,并且工作是并行的,资源分配是由操作系统来完成的,操作系统来决定程序cpu的控制权分配,所以一个多核cpu的工作效率大多体现在操作系统的分配上,因为一个CPU基本上可以执行很多个程序,通过PCB进程控制块的方式存储当前代码段,然后来回跳转,所以当你的CPU核过多时,操作系统在分配时可能会导致部分CPU闲置!

有序性

有序性指的是数据不相关的变量在并发的情况下,实际执行的结果和单线程的执行结果是一样的,不会因为重排序的问题导致结果不可预知。volatile, final, synchronized,显式锁都可以保证有序性。
volatile内存屏障插入策略:
在每个volatile写操作的前面插入一个StoreStore屏障。
在每个volatile写操作的后面插入一个StoreLoad屏障。
在每个volatile读操作的后面插入一个LoadLoad屏障。
在每个volatile读操作的后面插入一个LoadStore屏障。

Store:数据对其他处理器可见(即:刷新到内存中)
Load:让缓存中的数据失效,重新从主内存加载数据

volatile保证可见性原理

volatile内存屏障插入策略中有一条,“在每个volatile写操作的后面插入一个StoreLoad屏障”。
StoreLoad屏障会生成一个Lock前缀的指令,Lock前缀的指令在多核处理器下会引发了两件事:

  1. 将当前处理器缓存行的数据写回到系统内存。
  2. 这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。
jMM

1.硬件的发展中,一直存在一个矛盾,CPU、内存、I/O设备的速度差异。
速度排序:CPU >> 内存 >> I/O设备
为了平衡这三者的速度差异,做了如下优化:
CPU 增加了缓存,以均衡内存与CPU的速度差异;
操作系统增加了进程、线程,以分时复用CPU,进而均衡I/O设备与CPU的速度差异;
编译程序优化指令执行次序,使得缓存能够得到更加合理地利用。
2.JMM定义了线程和主内存之间的抽象关系:
线程之间的共享变量存储在主内存中(堆内存在线程之间共享,存储在堆内存中所有实例域、静态域和数组元素都是共享变量)
每个线程都有一个私有的本地内存,本地内存中存储了该线程用以读/写共享变量的副本
3.线程A与线程B通信:
线程A把本地内存A中的共享变量刷新到主内存中去。
线程B到主内存中去读取线程A之前已更新过的共享变量。
从整体来看,这个过程就是线程A在向线程B发送消息。这个通信过程必须要经过主内存。JMM通过控制主内存与每个线程的本地内存之间的交互,来为Java程序员提供内存可见性保证。
4.8种原子操作
在这里插入图片描述
5.JMM对volatile的特殊规则

volatile变量V,W,线程T,进行read load use assign store write操作:

对于T来说,必须保证对V的load和use连续一起出现,即在工作内存中,每次使用V前都必须先从主内存中刷新最新值,用于保证能看到其他线程对V的修改后的值。

T对V的assign和store必须连续一起出现。即在工作内存中,每次修改V后都必须立刻同步回主内存中,保证其他线程看到自己对V 的修改。

假定A是T对V的use assign,F是A相关联的load或store;P是和F相应的对变量V的read或write;同样,B是T对W的use或assign,G是B相关联的load或store,Q是G相应的对变量W的read或write。如果A先于B,那么P先于Q(volatile修饰的变量不会被指令重排序优化,保证代码的执行顺序与程序顺序相同)。

创建多线程方式

一共有3中创建多线程的方式,1.继承Thread类;2实现Runnable类;3.实现Callable接口.

区别

继承Thread类使用起来简单,但是java中的类的单继承限制其使用范围.
实现Runnable则提供了比较灵活的扩展,是最常用的方式.
使用Callable是因为,可以在Callable创建的线程中获取到线程的返回值.

实现一下Callable
public class RunMain {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //为了获取到结果,线程需要使用FutureTask类进行一下包装
        FutureTask<String> task = new FutureTask<>(new NewCallableThread());
        //然后使用Thread类在包装一下FutureTask类
        Thread thread = new Thread(task);
        thread.start();
        //该方法会阻塞当前线程,直到Callable线程执行完毕得出结果,才会获取.
        System.out.println(task.get());
    }
}

class NewCallableThread implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "这是Callable线程的返回值";
    }
}

三.线程状态

新建:采用 new 语句创建完成
就绪:执行 start 后
运行:占用 CPU 时间,处理任务
阻塞:执行了 wait 语句、执行了 sleep 语句和等待某个对象锁,等待输入的场合
终止:退出 run()方法
在这里插入图片描述

多线程使用

sleep和wait

sleep()

sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。

wait()

使用说明

Obj.wait(),与Obj.notify()必须要与synchronized(Obj)一起使用,也就是wait,与notify是针对已经获取了Obj锁进行操作。

从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){…}语句块内

从功能上来说wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。相应的notify()就是对对象锁的唤醒操作。

需要注意的是**notify()调用后,并不是马上就释放对象锁的,而是在相应synchronized(){}语句块执行结束,自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。**这样就提供了在线程间同步、唤醒的操作。Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。

创建一个线程安全的单例
public class SingleSafe {
    //无参构造私有化
    private SingleSafe() {}
    //对象属内存可见,禁止指令重排,防止出现空指针
    private volatile static SingleSafe singleSafe=null;

    public static SingleSafe getInstance() {
        //第一次判断是否为空,避免每次,每一个线程都进入同步锁.提高效率.
        if (null==singleSafe) {
            //添加同步锁
            synchronized (SingleSafe.class) {
                //第二次检测,避免其他线程创建,保证了同时只有一个线程在这里创建对象
                if (null==singleSafe) {
                    //创建对象
                    singleSafe = new SingleSafe();
                }
            }
        }
        return singleSafe;
    }

}
使用notify实现线程协同
package com.jd.thread;

/**
 * 实现线程的协同
 */
public class NotifyAndWait {
    //创建共享对象
    private static Object object = new Object();
    //创建轮询标志位,false为没有改变.true为变化了
    private static boolean flag = false;

    //创建一个等待线程
    static class WaitThread implements Runnable {
        @Override
        public void run() {
            //加锁
            synchronized (object) {
                //轮询当没有改变(false)等待
                while (!flag) {
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //当改变时执行任务
                System.out.println(Thread.currentThread().getName() + 
                		    "flag是" + flag + "等待被唤醒了,开始执行任务");
                //执行完成后将标志位回归原始
                flag = false;
            }
            //休眠一下
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //转入通知线程
            synchronized (object) {
                //当标志已经改变了就不在重复唤醒
                while (flag) {
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //当没有改变的时候要改变
                flag = true;
                //同时唤醒其他线程
                object.notifyAll();
                //额外输出
                System.out.println(Thread.currentThread().getName() +
                			 "flag是" + flag + "等待线程转入通知线程了");
            }
        }
    }

    //创建一个通知线程
    static class NotifyThread implements Runnable {
        @Override
        public void run() {
            //加个锁
            synchronized (object) {
                //当有其他线程改变了标志就不在改变
                while (flag) {
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //当状态没有发生该改变,执行任务
                System.out.println(Thread.currentThread().getName() + 
                					"flag是" + flag + "通知线程执行任务");
                //改变状态
                flag = true;
                object.notifyAll();
            }
            //休眠一下
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //转入等待线程
            synchronized (object) {
                while (!flag) {
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //额外输出
                System.out.println(Thread.currentThread().getName() +
                				 "flag是" + flag + "通知线程开始等待了");
            }
        }
    }

    //测试一下
    public static void main(String[] args) {
        Thread waitThread = new Thread(new WaitThread());
        Thread notifyThread = new Thread(new NotifyThread());
        waitThread.start();
        notifyThread.start();
    }
}
简单实现一个消费者和生产者
package com.jd.thread;

public class ProductAndConsumer {
    //创建商品的库存标志
    private static int num = 0;
    //共享对象
    private static Object object = new Object();

    //创建一个生产者
    static class Product implements Runnable {
        @Override
        public void run() {
            while (true) {
                //加锁
                synchronized (object) {
                    //当商品库存低于5时开始生产
                    while (num < 5) {
                        num++;
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("11111生产者生产一个商品" + num);
                        //唤醒消费者
                    }
                    //切记先唤醒在休眠
                    //唤醒消费者
                    object.notifyAll();
                    //超过5个
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }

    //创建一个消费者
    static class Consumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (object) {
                    //当库存高于1开始卖
                    while (num > 0) {
                        //开始售卖
                        num--;
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("22222消费者消费了一个商品" + num);
                    }
                    //切记先唤醒在休眠
                    object.notifyAll();
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
	//测试一下
    public static void main(String[] args) {
        Thread product = new Thread(new Product());
        Thread consumer = new Thread(new Consumer());
        product.start();
        consumer.start();
    }
}

Profinet从站开发初体验:用p-net开源库和树莓派快速搭建一个IO设备模拟器 本文详细介绍了如何使用p-net开源库和树莓派快速搭建Profinet从站IO设备模拟器。从开发环境准备、p-net源码编译到设备模拟器功能实现,提供了全流程实战指南,帮助开发者快速掌握工业通信协议开发技巧,适用于工业自动化领域的设备互联测试与验证。 阅读详情

相关推荐

从零开始掌握机械臂运动控制:原理、建模与实践

本文系统介绍了机械臂运动控制的核心原理与实践方法。从运动学与动力学建模的基础理论出发,详细解析了经典PID控制与现代MPC(模型预测控制)算法的应用,并通过ROS与MATLAB仿真案例,指导读者从零开始实现机械臂的轨迹规划与精准控制,为工业自动化应用提供完整的技术路径。

weixin_29099217的博客 563

C语言线程lock与unlock,谈谈线程同步Lock和unLock

Lock可以使用Condition进行线程之间的调度,它有更好的灵活性,而且在一个对象里面可以有多个Condition(即对象监视器),则线程可以注册在不同的Condition,从而可以有选择性的调度线程,更加灵活。Synchronized则使用Object对象本身的notify, wait, notityAll调度机制,相当于整个对象只有一个单一的Condition(即该对象本身)所有的线程都注...

weixin_34611130的博客 1552

fMRI脑影像特征提取——静息态与任务态,ALFF/fALFF和ReHo(Dpabi,Rest1.8)

任务态和静息态是大脑的两种状态,前者主要是指大脑在执行记忆、识别以及运动等具体任务时的状态,静息态则是指大脑不执行具体认知任务、保持安静、放松、清醒时的状态,是大脑所处的各种复杂状态中最基础和最本质的状态。任务态fMRI分析有非常悠远的历史,而静息态fMRI自1995年biswal教授及其同事率先报告静息态fMRI具有生理意义后,越来越多的人进入了静息态的研究领域。任务态fMRI主流的分析方法是模型驱动(GLM+HRF),也可以引用静息态fMRI

意疏的学习笔记 6万+

线程休眠

package xiancheng.sleep; /* * 线程休眠 demo * static void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行) * 此操作受到系统计时器和调度程序精度和准确性的影响 */ class XianChen...

weixin_30426879的博客 105

【Unity学习笔记】事件系统EventSystem

1.EventSystem物体 第一次在Unity中创建UI元素时,总会自动生成一个EventSystem物体,它包含三个组件:Transform、EventSystem、Standalone Input Module。如果我们把它删除了,会发现UI上的事件(比如点击、拖拽)将不会被检测到。没错,它就是用来处理UI相关的事件的。 1.1 EventSystem组件 EventSystem基于输入给物体发送事件,它在整个事件系统中扮演的主要角色是: 1.管理被选中的物体 2.管理正在使用的Input Modu

一白梦人的博客 1万+

Edge浏览器IE模式失效?最新142版本隐藏按钮的3种解决方案

本文针对Edge浏览器142版本中IE模式按钮消失的问题,提供了3种实用解决方案,包括注册表修改、手动添加网站到IE模式列表和企业策略部署方案,帮助用户解决兼容性问题,确保老旧系统正常访问。

weixin_28308325的博客 497

线程相关知识点

如果线程是 CPU 密集型的,那么多个线程同时运行会导致频繁的线程切换,增加了系统的开销,降低了效率。Java 使用的线程调度是抢占式的。操作系统通常会基于线程优先级和时间片来调度线程的执行,高优先级的线程通常获得 CPU 时间片的机会更多。并发编程的目的就是为了能提高程序的执行效率进而提高程序的运行速度,但是并发编程并不总是能提高程序运行速度的,而且并发编程可能会遇到很多问题,比如:内存泄漏、死锁、线程不安全等等。Java线程是基于作系统原生线程实现的,Java线程与作系统线程之间存在一一对应的关系。

2401_86844317的博客 1166

数据挖掘实战-基于长短期记忆网络(LSTM)的黄金价格预测模型 | 97% 准确度

本实验基于Kaggle上提供的从2013年到2023年的黄金价格数据集,运用长短期记忆网络(LSTM)构建了黄金价格预测模型。该数据集详细记录了每日的黄金价格信息,包括开盘价、收盘价、高点、低点和交易量等,为模型的训练提供了丰富的数据支持。

m0_64336780的博客 1万+

线程之相关知识点总结

介绍了线程的意义,线程与进程之间的关系,以及线程安全问题

m0_63904107的博客 1073

生成模型实战 | 基于Transformer生成音乐

本文介绍了基于Transformer架构的音乐生成方法,将音乐视为一系列事件序列进行处理。与将音乐表示为多维图像的MuseGAN不同,该方法使用类似GPT的仅解码器模型,基于先前事件预测下一个音乐事件。模型使用MIDI格式的钢琴音乐数据,通过分词处理将音符转换为note-on、note-off、time-shift和velocity四种事件类型,共388个独特词元,映射为索引序列后输入网络。训练完成后,可通过调整温度参数控制生成音乐的新颖性,从而创作出风格类似训练数据且连贯逼真的音乐作品。

盼小辉丶的博客 5816

从登录到应用可见:在 SAP S/4HANA Cloud Private Edition 中创建用户与打通 SAP Fiori 权限的完整思路

在SAP S/4HANA系统中,用户创建远非简单的账号开通,而是涉及认证、授权、数据访问等多维度的复杂过程。用户主数据记录(User Master Record)是系统访问的起点,包含登录方式、角色分配等关键信息。认证解决"你是谁"的问题,授权则决定"你能做什么"。SAP Fiori访问链路涉及Launchpad内容分配、应用启动映射、OData服务权限等多层校验。角色(Role)通过PFCG维护,包含业务目录(Catalog)和空间(Space)等元素,共同构成完整

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 148

线程相关知识点总结

1.线程的启动方式 开启主要有两种:继承Thread和实现cannable接口; 继承Thread: public class Practice { public static void main(String[] args) { // 继承 Thread 任务:copy文件 Copy c = new Copy(); c.start(); } } class Copy exte...

Biaoooos的博客 254

Spring AI Alibaba实战训练营-13语音生成应用开发指南

本文介绍了如何基于Spring AI Alibaba创建DashScope语音应用,支持文本转语音(TTS)和语音转文本(STT)功能。主要内容包括:1)环境准备要求Java 17+、Maven 3.6+及阿里云DashScope API Key;2)通过Spring Initializr创建项目并配置相关依赖;3)设置API密钥的安全配置方法;4)实现语音合成的同步和流式功能,包括创建控制器类、调用API接口及保存语音文件。文章提供了详细的代码示例和配置说明,帮助开发者快速搭建语音处理应用。

program哲学 403

Java线程相关知识点

一 进程是什么?线程是什么?两者有什么联系和区别? 1.1 进程:进程,直观点来说,保存在硬盘上的程序运行之后,会在内存空间形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,上级是操作系统。操作系统会 以进程为单位,分配系统资源(CPU时间片,内存等),进程是最小的资源分配单位; 1.2 线程:有时被称为轻量级的进程,是操作系统调度执行的最小单位 1.3 区别: 调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位 并发性:不仅进程之间可以并发,同一个进程的多个线程之..

Ankas 2947

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

多线程相关知识点

多线程知识点总结 1.进程与线程 1.1什么是进程 程序是静止的,只有真正运行时的程序,才被称之为进程。 单核CPU在任何时间点上,只能运行一个进程:宏观并行,微观串行。 1.2什么是线程 线程,又称轻量级进程(Light Weight Process)。程序中的一个顺序控制流程,同时也是CPU调度的基本单位。进程由多个线程组成,彼此间完成不同的工作,交替执行,成为多线程。 迅雷是一个进程,当中的多个下载任务即是多个线程。 Java虚拟机是一个进程,当中默认包含主线程(Main),可通过代

weixin_48304192的博客 398

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

线程池相关知识点

线程池是什么相信大家都是知道的,所以这里就不做解释了,直接看相关知识点吧。

qq_71416673的博客 1279

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Java中关于线程的相关知识点

线程 1.理解程序、进程、线程的概念 程序可以理解为静态的代码 进程可以理解为执行中的程序。 线程可以理解为进程的进一步细分,程序的一条执行路径 2.如何创建java程序的线程(重点) 方式一:继承于Thread类 class PrintNum extends Thread{ public void run()( //子线程执行的代码 for(int i= 1;i <= 100;i++) ...

Airuiliya520的博客 217

多线程的相关知识点

一、什么是线程,理解线程和进程的关系 线程理解:影分身 线程是进程里面的一条执行路径,每个线程同享进程里面的内存空间和系统资源 一个进程 -- 多线程:各个线程都有不同的分工 进程:进程之间的内存空间和系统资源是独立的 线程:线程之间是共享内存空间和系统资源的 进程里:可以有一条或一条以上的线程 进程里只有一条线程的情况下,这条线程就叫做主线程 进程里有多条线程

z90708833_yp的博客 276

线程相关的知识点

线程相关的知识点

weixin_57219176的博客 804

多线程相关知识点系统整理

摘要: 本文系统梳理了多线程编程的核心知识点。首先介绍了程序、进程、线程的基本概念及区别,阐述了单核与多核CPU的执行方式。详细讲解了三种线程创建方法:继承Thread类、实现Runnable接口和实现Callable接口,并比较了它们的优缺点。重点说明了线程特性、共享资源处理、同步机制及常用工具类(如CountDownLatch)。此外,还介绍了Lambda表达式简化线程创建的方法和常用Lombok注解。全文涵盖了从基础概念到高级特性的完整知识体系,为开发者提供了全面的多线程编程参考。

林冬的博客 713

Java线程池相关知识点总结

千千万万要记得:多刷题!!多刷题!!之前算法是我的硬伤,后面硬啃了好长一段时间才补回来,算法才是程序员的灵魂!!!!篇幅有限,以下只能截图分享部分的资源!!(1)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)(2)刷的算法题(还有左神的算法笔记)(3)面经+真题解析+对应的相关笔记(很全面)(4)视频学习(部分)ps:当你觉得学不进或者累了的时候,视频是个不错的选择在这里,最后只一句话:祝大家offer拿到手软!!

2401_84009065的博客 1103
上一篇: 简单使用适配器模式
下一篇: 在springboot中配置文件注入以及自定义配置文件
黑白格tt
博客等级 码龄8年 35粉丝 45原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值