Java多线程四个案例

Java多线程实现方式2:runnable接口、龟兔赛跑案例 实现Runnable 定义MyRunnable类实现Runnable接口 实现run()方法,编写线程执行体 创建线程对象,调用start()方法启动线程 案例: package MyDemo; //创建线程方式2:实现runnable接口 //1.实现接口 //2.重写run方法 //3.创建runbale接口实现类的对象。 //启动线程。需要创建一个线程Thread对象 , 然后把runb... 阅读详情

目录

一,单例模式

单例模式也就是一个进程中只允许有一个实例,是我们平时在开发中比较重要常见的一种模式,我们单例模式一般分为两种,一种是饿汉模式,一种是懒汉模式

饿汉模式:

//饿汉模式
class Singleton{
    //static保证了成员或者方法是属于类的,不属于实例,所以你不能通过new实例来调用它,刚刚好保证单例,因为new实例会创建多个对象
    private static Singleton instance=new Singleton();
    //单例模式最关键的
    private Singleton(){
    }
    public static Singleton getInstance(){
        return instance;
    }
}

在饿汉模式里面,我们调用的开始就直接创建了唯一实例,所以线程安全,因为没有判断等其他操作,只有读的操作

懒汉模式(原始):

class Singleton3 {
    private static Singleton3 instance;
    private Singleton3() {
    }
    public static Singleton3 getInstance() {
        if (instance == null) {
            instance = new Singleton3();
        }
        return instance;
    }
}

在get方法里面判断了是否创建过实例之后再来操作,但是这样的懒汉模式线程不安全,当我们两个线程同时判定是否为空的时候,可能就会出现创建了两个instance实例,单例模式就失败了,并且new操作会因为指令重排序导致出现问题,指令重排序:编译器的一种底层优化,调整指令执行顺序,使代码效率更高。

(1)就比如new这个操作可以简化理解为三个操作:1:分配内存空间,2:针对空间进行初始化,3:内存空间首地址,赋值到引用变量中。按正常顺序,我们应该是123,但是经过指令重排序会导致变成132,就会传回去一个没有数据的值。

(2)并且外层还有if判断,加上new操作,就会使这个创建操作不是原子的,也会因为线程的随机调度导致线程安全问题,所以我们要在instance变量前面加上volatile修饰,防止指令重排序,并且在if和new的这个操作外层套上一把锁,将两个操作打包为一个整体。

(3)但是我们还需要思考一个问题,当我们第一次创建好实例之后,就不需要每次都使用锁然后判断了,这样会浪费时间和内存空间,所以我们外层需要再使用一层if判断

懒汉模式(改进):

class Singleton2 {
    private static volatile Singleton2 instance;
    private Singleton2() {
    }
    public static Singleton2 getInstance() {//双重检查
        if (instance == null) {
            synchronized (Singleton2.class) {
                if (instance == null) {
                    instance = new Singleton2();
                }
            }
        }
        return instance;
    }
}

总结一下单例模式注意线程安全需要注意的点1:正确的加锁,2:双重if判断,3:volatile

dataSource实现单例:

//dataSource实现单例模式
class DataSource {
    private static volatile DataSource dataSource;
    private DataSource() {
    }
    public static DataSource getInstance() {
        if (dataSource == null) {
            synchronized (DataSource.class) {
                if (dataSource == null) {
                    DataSource ds=new DataSource();
                    dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/java117?characterEncoding=utf8&useSSL=false&serverTimezone=UTC");
                    dataSource.setUser("root");       // 你的mysql账号
                    dataSource.setPassword("你的密码"); // 你的mysql密码
                    dataSource=ds;
                }
            }
        }
        return dataSource;
    }
}

这里有个注意点,就是我们用来一个ds这样的零时变量,最后再赋值回去,这样的作用是什么:因为有指令重排序这样的问题,所以如果没有这个零时变量,其他线程可能最坏情况下拿到还没初始化,并且还没有set的database对象,因为即使有锁,外线程依旧可以拿到里面的对象,因为DataSource是static修饰的,所有线程是共用的这一个

二,阻塞队列

队列特点:先进先出

阻塞队列的特点:1:线程安全,2:阻塞功能(阻塞队列为空的时候尝试出的时候,队列满尝试入的情况)

阻塞功能可以帮助实现生产者-消费者模型:1:降低资源的竞争,2:解决耦合(耦合就是代码功能的关联性,我们追求低耦合,关联性越低越好),3:削峰填谷(可以使请求高峰以及请求低谷的时候,服务器依旧可以按照自己的节奏来执行)

生产者-消费者的不足:1:单个请求的响应时间会受影响,2:使服务器结构更加复杂,3:这个模型更适合异步

阻塞队列的相关方法展示:

方便分为峰值和谷值来展示


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

//阻塞队列
public class demo8 {
    //生产快,但是消费慢,因为消费要有sleep,所以队列就产生了阻塞,每次保证队列只有两个元素
    //如果我不设置队列大小,不用阻塞队列,生产者就会疯狂的生成,然后占满内存,抛出异常
    public static void main1(String[] args) {
        BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(2);
        //生产者
        Thread t1=new Thread(()->{
            for (int i = 0; i < 500; i++) {
                try {
                    blockingQueue.put(i);
                    System.out.println("生产了"+i);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        //消费者
        Thread t2=new Thread(()->{
            for (int i = 0; i < 500; i++) {
                try {
                    Thread.sleep(500);
                    int take=blockingQueue.take();
                    System.out.println("消费了"+take);

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t1.start();
        t2.start();
    }
    //消费快,生成慢
    public static void main(String[] args) {
        BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(2);
        //生产者
        Thread t1=new Thread(()->{
            for (int i = 0; i < 500; i++) {
                try {
                    Thread.sleep(500);
                    blockingQueue.put(i);
                    System.out.println("生产了"+i);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        //消费者
        Thread t2=new Thread(()->{
            for (int i = 0; i < 500; i++) {
                try {
                    int take=blockingQueue.take();
                    System.out.println("消费了"+take);

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t1.start();
        t2.start();
    }
}

对于代码的解释:如果我们不使用阻塞队列进行阻塞的话,会出现

1:瞬时流量洪峰:生产者疯狂生成任务,消费处理不过来 → 队列满,生产者 put 阻塞(防止 OOM)。

什么是OOM:JVM 堆内存已经全部用光,还想继续创建新对象,JVM 直接抛OutOfMemoryError异常,程序直接崩溃。

2:流量低谷:没有新任务产生,队列全部消费完 → 队列空,消费者 take 阻塞,CPU 不轮询空转

什么是空转:线程一直在 CPU 循环做无效判断,啥业务活不干,但是一直占用 CPU,白白消耗 CPU 资源。

阻塞队列就很好地解决了以上的问题

自己实现简单的阻塞队列:

//自己创建的阻塞队列
class MyBlockingQueue{
    Object locker=new Object();
    private String[] array = new String[1000];
    private int head = 0;
    private int tail = 0;
    private int size = 0;
    public MyBlockingQueue(int capacity){
        array=new String[capacity];
    }
    public void put(String elm) throws InterruptedException {
        synchronized (locker) {
            //队列是满的
            while (size == array.length) {
                locker.wait();
            }
            //队列不满开始放东西
            array[tail] = elm;
            tail++;
            if (tail >= array.length) {
                tail = 0;
            }
            size++;
            locker.notify();
        }
    }
    public String take() throws InterruptedException {
        synchronized (locker) {
            //当队列为空的时候
            while (size==0){
               locker.wait();
            }
            //当队列不为空的时候
            String elm = array[head];
            head++;
            if (head >= array.length) {
                head = 0;
            }
            size--;
            locker.notify();
            return elm;
        }
    }
}

public class demo3 {
    public static void main(String[] args) {
        MyBlockingQueue myBlockingQueue=new MyBlockingQueue(2);
        //生产者
        Thread t1=new Thread(()->{
            for (int i = 0; i < 500; i++) {
                try {
                    Thread.sleep(500);
                    myBlockingQueue.put(i+"");
                    System.out.println("生产了"+i);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        //消费者
        Thread t2=new Thread(()->{
            for (int i = 0; i < 500; i++) {
                try {
                    String take=myBlockingQueue.take();
                    System.out.println("消费了"+take);

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t1.start();
        t2.start();
    }
}

阻塞我们用到的是wait和notify的组合,因为我们需要达成某种条件才会阻塞,并且达到某种条件才会唤醒,不能单纯的sleep以及join,并且我们这里用到的循环是while,因为while可以有再次判断的机制

三,线程池

当我们刚引入线程的时候,我们会发现线程比进程好太多了,但是接下来我们还是会发现线程的使用开销也大了一些,所以我们再引入了线程池,也就是把线程提前创建好放在里面,这样就比操作系统创建的效率来的更高

这是一台电脑的基本组成,当我们调用start来创建线程的时候,我们会有从用户态到内核态再到用户态的切换,这样会消耗一些时间和内存,但是线程池是纯用户态的操作,会更加节省开销

线程池的构造

我们来介绍一下这里的参数

(1)corePoolSize(核心线程数),maximumPoolSize(最大线程数)

这里涉及到两类线程1:核心线程(在创建线程池当初就已经有了)2:非核心线程(因为任务太多额外创建的),两者相加就是最大线程数

(2)keepAliveTime (数值),unit(单位)

这里描述了非核心现场释放的时机

(3)workQueue(任务队列)

这里放要执行的任务,并且可以保证线程安全,可以让调用者手动指定队列

(4)threadFactory(线程工厂)

工厂设计模式:有一个工厂类,可以不依赖构造方法

可以自己提供工厂类,当然也可以用系统提供的工厂类(里面有两种)

(5)handler(拒绝策略)

任务队列到达上限,就会触发拒绝策略,主要有四种1:抛出异常,

2:调用submit这个线程自己负责来执行,

3:把任务队列中,最老的任务丢弃,把空的留给新的,

4:把任务队列中,最近添加的任务丢弃,把空的留给更加新的

线程池的创建

MyThreadFactory myThreadFactory=new MyThreadFactory("消息业务",false);
        ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(
                2,
                4,
                2,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(10),
                myThreadFactory,
                new ThreadPoolExecutor.AbortPolicy()
        );
package thread;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public class MyThreadFactory implements ThreadFactory {
    //获取旧的编号,并且进行自增
    private final AtomicInteger threadIndex = new AtomicInteger(1);
    private final String threadName;
    private final boolean isDaemon;
    public MyThreadFactory(String threadName, boolean isDaemon) {
        this.threadName = threadName;
        this.isDaemon = isDaemon;
    }
    @Override
    public Thread newThread(Runnable r) {
        //先自定义名字
       String threadname= this.threadName + threadIndex.getAndIncrement();
       //创建线程
        Thread thread = new Thread(r,threadname);
        //设置守护线程
        thread.setDaemon(isDaemon);
        //设置未捕获异常处理器:线程运行抛出异常会进入这里
        thread.setUncaughtExceptionHandler((t, e) -> {
            System.err.println("【线程异常】线程名:" + t.getName() + ",异常信息:" + e.getMessage());
            e.printStackTrace();
        });
        return thread; // 返回给线程池使用
    }
}

这是我们自己创建了一个线程工厂然后传入进去,当然我们也可以用操作系统自带的

不过操作系统还提供了一个更加简单的构造方法,使用Excutor这个工厂类来创建线程池

前面两个是普通线程池,可以自动扩容,三四是指定了线程池的大小,六七十控制在未来的某个时间点执行,其他的可以自行去了解一下

并且我们往线程池中添加任务是使用submit关键字

自己实现固定数量的线程池

//自己创建线程池
class MyThreadPool{
    private BlockingQueue<Runnable> blockingQueue=new ArrayBlockingQueue<>(10);
    public void submit(Runnable runnable) throws InterruptedException {
        blockingQueue.put(runnable);
    }
    //添加构造方法
    public MyThreadPool(int size){
        for (int i = 0; i < size; i++) {
            Thread t=new Thread(()->{
                    try {
                        while (true) {
                        Runnable runnable = blockingQueue.take();
                        runnable.run();}
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
            });
            t.start();
            t.setDaemon(true);
        }

    }
}

四,定时器

定时器就和闹钟一样,在规定时间后进行执行

定时器的使用

public static void main(String[] args) throws InterruptedException {
        Timer timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("定时任务执行了");
            }
        },1000);
        Thread.sleep(2000);
        timer.cancel();
    }

自己实现简易定时器

自己实现定时器的主要要点:(1)因为编译器的定时器需要我们传入任务然后时间,所以我们也需要创建一个任务类,里面定义了runnable以及时间(有时间间隔delay,也有任务时间time)

(2)我们用到优先级队列来存储任务,并且在任务类里面添加比较方法,让优先级队列知道是通过时间来进行排序的

(3)通过锁来使操作原子化,并且锁的位置也很重要

(4)通过wait/notify来进行阻塞等待以及唤醒,第一个wait是等待队列不为空,第二个等待是为了等待到达任务的执行时间,两个等待同时因为schedule方法里面的notify来唤醒,因为第一个等待本身就是等待不为空,schedule方法里面添加了方法所以就唤醒,第二个是因为可能新添加的任务时间更早,可能需要重新排序,但是在我们add方法执行后的瞬间就会重新进行排序了,所以同时在这里唤醒就是合理的

import java.util.PriorityQueue;
//自己实现定时器
//先得有一个任务类,定时器中的任务在这里编写以及初始化
class TimerTask implements Comparable<TimerTask>{
    private Runnable runnable;
    //目的是判定是否到达执行时间
    private long time;
    //delay是时间间隔
    public TimerTask(Runnable runnable, long delay) {
        this.runnable = runnable;
        this.time = System.currentTimeMillis() + delay;
    }
    //在MyTimer里面通过run方法进行执行
    public void run(){
        runnable.run();
    }
    public long getTime() {
        return time;
    }

    @Override
    public int compareTo(TimerTask o) {
        return (int)(this.time - o.time);
    }
}
class MyTimer {
    Object locker =new Object();
    private PriorityQueue<TimerTask> queue = new PriorityQueue<>();

    public void schedule(Runnable runnable, long delay) {
        synchronized (locker){
            TimerTask timerTask = new TimerTask(runnable, delay);
            queue.add(timerTask);
            locker.notify();
        }
    }

    //去执行任务
    public MyTimer() {
        Thread thread = new Thread(() -> {
            while (true) {
                synchronized (locker) {
                    TimerTask timerTask = queue.peek();
                    try {
                        while (timerTask == null) {//队列为空
                            locker.wait();
                            timerTask = queue.peek();
                        }
                        long currentTime = System.currentTimeMillis();
                        if (currentTime >= timerTask.getTime()) {//到达执行时间
                            queue.poll().run();
                        } else {
                            locker.wait(timerTask.getTime() - currentTime);
                        }
                    }catch (InterruptedException e){
                        throw new RuntimeException("wait被终止");
                    }
                }
            }
        });
        thread.setDaemon(true);
        thread.start();
    }
}
public class demo12 {
    public static void main(String[] args) throws InterruptedException {
        MyTimer myTimer = new MyTimer();
        myTimer.schedule(() ->
            System.out.println("定时任务执行了1000"), 1000);
        myTimer.schedule(() ->
                        System.out.println("定时任务执行了2000"), 2000);
        myTimer.schedule(() ->
                        System.out.println("定时任务执行了3000"), 3000);
        Thread.sleep(5000);
    }
}

Ubuntu22.04安装ROS1 代表使用 2 线程进行编译,可以根据 CPU 适当调整。如果出现小乌龟窗口,说明安装成功 🎉!启动成功,则打开另一个终端,测试。需要解决一些兼容性问题,因为。由于 Ubuntu 22.04。过程,确保成功安装。 阅读详情

相关推荐

IGBT基础知识

IGBT

u010783226的专栏 1万+

Java学习路线-16:多线程综合案例

第6 章 : 多线程综合案例 23 数字加减 4个线程,2个线程加,2个线程减 循环出现 加一个,减一个 // 资源 class Resource { private int count = 0; // 为false可以增加,加完了设置为true, // 为true可以减少,减完了设置为false private boolean flag = false; ...

彭世瑜的博客 1224

UI-TARS本地部署

UI-TARS是一个用于本地部署的交互控制模型,支持桌面应用的自动化操作。部署步骤包括:首先,从官方GitHub仓库下载项目源码和模型checkpoint;其次,使用vLLM框架进行本地模型部署,启动API服务;最后,通过客户端调用API实现功能。部署过程中可能遇到pynvml模块或模型配置问题,提供了相应的解决方案。此外,还支持通过UI-TARS-Desktop客户端进行本地桌面应用的交互控制。整体流程旨在帮助用户快速实现UI-TARS的本地部署与应用。

DYF的博客 2531

java多线程的经典案例_Java多线程经典案例

Java多线程经典案例 /** * 典型案例:子线程执行10次,主线程执行100次,两者交替50次。 */package cn.itcast.lesson4;public clJava多线程经典案例/*** 典型案例:子线程执行10次,,主线程执行100次,两者交替50次。*/package cn.itcast.lesson4;public class TestWaitNotify {public...

weixin_30678347的博客 341

Quartus Prime v18.1 standard-QuartusPrimeV18.1标准版安装过程

Quartus Prime v18.1 standard安装破解过程 下载方式1:官网下载: https://fpgasoftware.intel.com/18.1/?edition=standard&platform=windows 下载方式2:可以从我的网盘下载安装包(如果链接未时效的话): 链接:https://pan.baidu.com/s/1bq4_FcNPSflU1zGJv__rvA 提取码:o0in ----------------------------------.

Alonger1988的博客 2万+

cst-python联合仿真的问题解决

cst与python联合仿真出现无法调用CST的问题解决

ayihu_的博客 2374

Java 多线程案例

多线程案例

小钟不想敲代码 2906

74HC165级联踩坑实录:STM32读取32路开关状态,时序调试与常见问题排查

本文详细介绍了74HC165级联在STM32读取32路开关状态时的时序调试与常见问题排查。从硬件设计的PCB布局优化、电源噪声控制,到软件时序的精确调校和数据采集策略,提供了完整的解决方案。通过逻辑分析仪和示波器的高效使用,解决了信号延迟和干扰问题,最终实现了稳定可靠的32路信号读取。

weixin_34046298的博客 314

JAVA多线程实现案例

1.继承Thread类实现多线程的格式权限修饰符类名extendsThread{}2.实现Runnable接口实现多线程的格式权限修饰符类名implementsRunnable{}1.通过继承Thread类本身。2.通过实现Runnable接口。3.通过Callable和Future创建线程池。Thread类本身也是实现了Runnable接口来达到开启线程的目的。.........

weixin_52014130的博客 3810

实战避坑:基恩士KV8000 PLC与C#上位机链路通讯全流程实现(含ST代码+上位机源码)

本文详细讲解了基恩士KV8000 PLC与C#上位机的TCP链路通讯实现,从PLC端的ST代码编写、通讯配置,到上位机的通讯类封装、界面实现,再到实战避坑和性能优化,提供了完整的可复用方案。该方案已在实际产线项目中验证,支持实时数据采集和控制指令下发,稳定性和可靠性满足工业场景需求。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1179

YOLO算法:关于目标检测算法的基本介绍(小白入门必读)

目标检测算法是一种计算机视觉算法,用于在图像或视频中识别和定位特定的目标物体。本节课就给大家重点介绍下基于深度学习的目标检测算法!

小哥谈 2525

java多线程死锁案例(代码案例)

java多线程死锁案例(代码案例) 什么是死锁 当一个线程拥有A对象锁,并等待B对象锁的时候,另一个线程拥有B对象锁,并等待A对象锁,这就造成了死锁。 一个线程可以同时拥有多个对象的锁标记,当线程阻塞时,不会释放已经拥有的锁标记,也可能会造成死锁。 案例介绍: 假如宿舍只剩一双鞋,这时候小明和小朋两个人都要出去,两个人一个拿到了左脚鞋子,一个人拿到了右脚鞋子,可是谁也不让给谁,于是乎就造成了死锁现象,谁也别出去了。 package com.nxw.Thread.dieLock; public clas

Silence-wen 2326

【学习系列】SAP RAP 3:添加多层级的子节点

本文详细介绍了在SAP ABAP RAP开发中如何创建多层级业务对象。主要内容包括:1)创建明细和计划行层级的数据库表及CDS视图;2)使用association和composition关键字建立父子关联关系;3)创建各层级的投影视图并设置层级关系;4)更新行为定义,添加关联、操作权限等控制;5)更新服务定义公开新增视图;6)创建元数据扩展优化UI展示。通过这一系列步骤,实现了从抬头到明细再到计划行的完整业务对象层级结构,为后续UI功能扩展奠定了基础。

DeveloperMrMeng的博客 591

Java多线程(卖票案例)

1.卖票案例需求分析 某天某个景区售票,门票票只有100张,景区有三个售票窗口,同时售票,共享票源(100张) 通过多线程的方式实现三个售票窗口同时售票 首先要明确票源只能有一个 其次需要创建三个Thread的对象去执行卖票的方法,卖完票后要将剩余的票数返回给统一的票源; 2.代码实现 1.票源和多线程执行入口代码 public class Ticket implements Runnable { private int tickets = 100; //票源 TicketOffi

qq_39586519的博客 4846

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

深度学习工具包 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")

【Java】多线程售票案例

java多线程卖票案例

RedMaple 903

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

java中多线程编程案例_java多线程编程的概述以及案例详解

引子: java编程中有时候会要求线程安全(注:多个线程同时访问同一代码的时候,不会产生不同的结果。编写线程安全的代码需要线程同步),这时候就需要进行多线程编程。从而用到线程间通信的技术。那么在java里面,线程间通信是怎么实现的?这篇文章将通过一个案例详细分析。文章关键词: Object,wait,notify,notifyAll,锁,同步(synchronized).详解一个经典的生产者消费...

weixin_35976825的博客 154

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

java多线程使用详解与案例,超详细

java多线程使用 java使用多线程的三种方式: 继承Thread类,并重写run方法。 实现Runnable接口,重写run方法 实现Callable<返回值>接口,重写call方法 实例如下 继承Thread class test extends Thread{ @Override public void run() { System.out.println("你好啊"); } } 开始启动线程: new test().start() 实现R

languageStudent的博客 3万+

Java 多线程工作之CompletableFuture.runAsync案例

Java 多线程工作之CompletableFuture.runAsync案例

扣脚老骚 982

linux下java多线程_Java多线程经典案例

Java多线程经典案例/*** 典型案例:子线程执行10次,主线程执行100次,两者交替50次。*/package cn.itcast.lesson4;public class TestWaitNotify {public static void main(String[] args){final Business business= new Business();new Thread(new R...

weixin_35916106的博客 183

【Java篇】Java多线程完成火车票售卖案例

我们在学习Java多线程时,可能最典型的一个案例就是火车票售卖,那么如何在不重复售票的情况下卖出全部火车票,我们通过Java多线程来完成,并根据 synchronized 同步锁关键字来限制同时卖出一张票的情况!

破烂码农 4480

Java多线程案例及其代码实现

目录 案例一:单例模式 1.饿汉模式的代码实现 2.懒汉模式 案例二:阻塞队列 1.线程安全 2.产生阻塞效果 1.如果队列为空,尝试出队列,就会出现阻塞现象,阻塞到队列不为空为止。 2.如果队列未满,尝试入队列,也会出现阻塞,阻塞到队列不为满为止。 案例三:定时器 1.描述任务 2.组织任务(使用一定的数据结构把这些任务给放到一起) 3.执行时间到了的任务 案例四:线程池 案例一:单例模式 线程安全的单例模式有两种典型实现: 1.饿...

weixin_59771320的博客 8899

Java多线程学习的关键要点和常见案例总结

Java多线程学习的关键要点和常见案例总结

qqrrjj2011的博客 1211

Java多线程:同步的案例

本文记录Java多线程同步的案例。 背景:银行(Bank)里面有多个账户,将两个账户进行转账(调用Bank对象的transfer方法),这在个过程中,银行里钱的总额保持不变。 客户端:开启多个线程进行转账操作 import java.util.Random; /** * UnsynchBankTest */ public class UnsynchBankTest { pu...

hefrankeleyn的博客 382

Java多线程之龟兔赛跑的案例

大家好,今天分享一下Java多线程之龟兔赛跑的案例 源码: package Demo01; //这是一个龟兔赛跑的实际案例 public class Race implements Runnable { private static String winner; //胜利者 @Override public void run() { //重写run()方法 for (int i = 0; i <=100; i++) { /

weixin_47556601的博客 3156

java关于多线程的小案例——购票小案例

1.Tickets类实现Runnable接口 class Tickets implements Runnable { //票数总共为100 private int ticket = 100; public void run() { while(true) { if(ticket > 0) { System.out.println(Thread.currentThread().getName() + "

weixin_41531181的博客 387

java lambda 多线程 案例分享

多线程、循环输出(异步)0。 thread 进行循环异步 Thread newThread = new Thread(() lambda 表达式 多线程

二等碗 617
上一篇: 多线程初阶
下一篇: AVL树的实现(Java版)
忙着追剧的村长
博客等级 码龄1年 586粉丝 50原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值