Java多线程创建及典型实例(多线程买票)

news2025/1/12 7:40:49

Java多线程创建及典型实例(多线程买票)

  • 多线程
    • 1. Thread
    • 2. Runnable
    • 3. 线程通信
    • 4. Callable
    • 5. 线程池
  • 多线程卖票实例
    • 1. 继承Thread类(存在线程安全问题)
    • 2. 实现Runnable接口(存在线程安全问题)
    • 3. 对线程安全问题的解决
      • 3.1 Runnable(同步代码块)
      • 3.2 Thread(同步代码块)
      • 3.3 Runnable(同步方法)
      • 3.4 Thread(同步方法)
      • 3.5 Lock解决线程安全问题

请添加图片描述

多线程

1. Thread

第一种方式创建多线程

package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) {
        new MyThread().start();
        System.out.println(Thread.currentThread().getName()); // main
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(i + Thread.currentThread().getName());
        }
    }
}
package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) throws InterruptedException {
        new MyThread().start();
        Thread.sleep(10);
        System.out.println(Thread.currentThread().getName()); // main
        Thread.currentThread().setName("主线程");
        System.out.println(Thread.currentThread().getName());
        System.out.println(Thread.currentThread().isAlive());
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
        System.out.println(Thread.currentThread().getPriority()); // 5
    }
}

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(i + Thread.currentThread().getName() + " " + getPriority());
        }
    }
}

2. Runnable

第二种方式创建多线程

package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) {
        Window window = new Window();
        Thread thread1 = new Thread(window);
        Thread thread2 = new Thread(window);
        Thread thread3 = new Thread(window);
        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread3.setName("窗口3");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

class Window implements Runnable {

    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            if (ticket > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":票号:" + ticket--);
            } else {
                break;
            }
        }
    }
}

3. 线程通信

线程通信:线程1、2交替打印数字1-100

package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) {
        Number number = new Number();
        Thread thread1 = new Thread(number);
        Thread thread2 = new Thread(number);
        thread1.start();
        thread2.start();
    }
}

class Number implements Runnable {
    private int num = 1;
    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                notify();
                if (num < 100) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":" + num++);
                }
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4. Callable

第三种方式创建多线程

package JavaPackage_13;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class JavaCode {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(myThread);
        Thread thread = new Thread(futureTask);
        thread.start();
        try {
            // 获取返回值
            Integer sum = futureTask.get();
            System.out.println(sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

class MyThread implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i <= 100; i++) {
            sum += i;
        }
        return sum;
    }
}

5. 线程池

第四种方式创建多线程

线程池创建多线程

	package JavaPackage_13;

import java.util.concurrent.*;

public class JavaCode {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10); // 接口
        ThreadPoolExecutor service = (ThreadPoolExecutor) executorService;
        //设置属性
        service.setCorePoolSize(15);
        try {
            System.out.println(executorService.submit(new MyThread()).get());// 适用于Callable
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        executorService.execute(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println(i + Thread.currentThread().getName());
                }
            }
        }); // 适用于Runnable
        //关闭连接池
        executorService.shutdown();
    }
}

class MyThread implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i <= 100; i++) {
            sum += i;
        }
        return sum;
    }
}

多线程卖票实例

1. 继承Thread类(存在线程安全问题)

package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) {
        Window window1 = new Window();
        Window window2 = new Window();
        Window window3 = new Window();
        window1.setName("窗口1");
        window2.setName("窗口2");
        window3.setName("窗口3");
        window1.start();
        window2.start();
        window3.start();
    }
}

class Window extends Thread {

    private static int ticket = 100;

    @Override
    public void run() {
        while (true) {
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + ":票号:" + ticket--);
            } else {
                break;
            }
        }
    }
}

2. 实现Runnable接口(存在线程安全问题)

package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) {
        Window window = new Window();
        Thread thread1 = new Thread(window);
        Thread thread2 = new Thread(window);
        Thread thread3 = new Thread(window);
        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread3.setName("窗口3");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

class Window implements Runnable {

    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            if (ticket > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ":票号:" + ticket--);
            } else {
                break;
            }
        }
    }
}
窗口1:票号:100
窗口3:票号:100
窗口2:票号:100
窗口2:票号:99
窗口3:票号:97
窗口1:票号:98
窗口2:票号:96
窗口3:票号:95
窗口1:票号:94
窗口2:票号:93
窗口3:票号:92
窗口1:票号:91
窗口3:票号:90
窗口2:票号:90
窗口1:票号:89
窗口3:票号:88
窗口2:票号:87
窗口1:票号:86
窗口3:票号:85
窗口2:票号:84
窗口1:票号:83
窗口3:票号:82
窗口2:票号:81
窗口1:票号:80
窗口3:票号:79
窗口2:票号:78
窗口1:票号:77
窗口3:票号:76
窗口2:票号:75
窗口1:票号:74
窗口3:票号:73
窗口2:票号:72
窗口1:票号:71
窗口3:票号:70
窗口2:票号:69
窗口1:票号:68
窗口3:票号:67
窗口2:票号:66
窗口1:票号:65
窗口3:票号:64
窗口2:票号:63
窗口1:票号:62
窗口3:票号:61
窗口2:票号:60
窗口1:票号:59
窗口3:票号:58
窗口2:票号:57
窗口1:票号:56
窗口3:票号:55
窗口2:票号:54
窗口1:票号:53
窗口3:票号:52
窗口2:票号:51
窗口1:票号:50
窗口3:票号:49
窗口2:票号:48
窗口1:票号:47
窗口3:票号:46
窗口2:票号:45
窗口1:票号:44
窗口3:票号:43
窗口2:票号:42
窗口1:票号:41
窗口3:票号:40
窗口2:票号:39
窗口1:票号:38
窗口3:票号:37
窗口2:票号:36
窗口1:票号:35
窗口3:票号:34
窗口2:票号:33
窗口1:票号:32
窗口3:票号:31
窗口2:票号:30
窗口1:票号:29
窗口3:票号:28
窗口2:票号:27
窗口1:票号:26
窗口3:票号:25
窗口2:票号:24
窗口1:票号:23
窗口3:票号:22
窗口2:票号:21
窗口1:票号:20
窗口3:票号:19
窗口2:票号:18
窗口1:票号:17
窗口3:票号:16
窗口2:票号:15
窗口1:票号:14
窗口3:票号:13
窗口2:票号:12
窗口1:票号:11
窗口3:票号:10
窗口2:票号:9
窗口1:票号:8
窗口3:票号:7
窗口2:票号:6
窗口1:票号:5
窗口3:票号:4
窗口2:票号:3
窗口1:票号:2
窗口3:票号:1
窗口2:票号:0
窗口1:票号:-1

Process finished with exit code 0

3. 对线程安全问题的解决

通过同步机制解决线程安全问题

3.1 Runnable(同步代码块)

可以考虑使用this充当同步监视器

synchronized(同步监视器[]){ // 任何一个类的对象都可以充当锁 多个线程必须要共用同一把锁
    被同步的代码
}

操作同步代码时,只能有一个线程参与,其他线程等待,效率低。

package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) {
        Window window = new Window();
        Thread thread1 = new Thread(window);
        Thread thread2 = new Thread(window);
        Thread thread3 = new Thread(window);
        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread3.setName("窗口3");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

class Window implements Runnable {

    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":票号:" + ticket--);
                } else {
                    break;
                }
            }
        }
    }
}
窗口1:票号:100
窗口1:票号:99
窗口1:票号:98
窗口1:票号:97
窗口1:票号:96
窗口1:票号:95
窗口1:票号:94
窗口1:票号:93
窗口1:票号:92
窗口1:票号:91
窗口1:票号:90
窗口1:票号:89
窗口1:票号:88
窗口1:票号:87
窗口1:票号:86
窗口1:票号:85
窗口1:票号:84
窗口1:票号:83
窗口1:票号:82
窗口1:票号:81
窗口1:票号:80
窗口1:票号:79
窗口1:票号:78
窗口1:票号:77
窗口1:票号:76
窗口1:票号:75
窗口1:票号:74
窗口1:票号:73
窗口1:票号:72
窗口1:票号:71
窗口1:票号:70
窗口1:票号:69
窗口1:票号:68
窗口1:票号:67
窗口1:票号:66
窗口1:票号:65
窗口1:票号:64
窗口1:票号:63
窗口1:票号:62
窗口1:票号:61
窗口1:票号:60
窗口1:票号:59
窗口1:票号:58
窗口1:票号:57
窗口1:票号:56
窗口1:票号:55
窗口1:票号:54
窗口1:票号:53
窗口1:票号:52
窗口1:票号:51
窗口1:票号:50
窗口1:票号:49
窗口1:票号:48
窗口1:票号:47
窗口1:票号:46
窗口1:票号:45
窗口1:票号:44
窗口1:票号:43
窗口1:票号:42
窗口1:票号:41
窗口1:票号:40
窗口1:票号:39
窗口1:票号:38
窗口1:票号:37
窗口1:票号:36
窗口1:票号:35
窗口1:票号:34
窗口1:票号:33
窗口1:票号:32
窗口1:票号:31
窗口1:票号:30
窗口1:票号:29
窗口1:票号:28
窗口1:票号:27
窗口1:票号:26
窗口1:票号:25
窗口1:票号:24
窗口1:票号:23
窗口1:票号:22
窗口1:票号:21
窗口1:票号:20
窗口1:票号:19
窗口1:票号:18
窗口1:票号:17
窗口1:票号:16
窗口1:票号:15
窗口1:票号:14
窗口1:票号:13
窗口1:票号:12
窗口1:票号:11
窗口1:票号:10
窗口1:票号:9
窗口1:票号:8
窗口1:票号:7
窗口1:票号:6
窗口1:票号:5
窗口1:票号:4
窗口1:票号:3
窗口1:票号:2
窗口1:票号:1

Process finished with exit code 0

3.2 Thread(同步代码块)

可以考虑使用当前类xxx.class充当同步监视器

package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) {
        Window window1 = new Window();
        Window window2 = new Window();
        Window window3 = new Window();
        window1.setName("窗口1");
        window2.setName("窗口2");
        window3.setName("窗口3");
        window1.start();
        window2.start();
        window3.start();
    }
}

class Window extends Thread {

    private static int ticket = 100;

    @Override
    public void run() {
        while (true) {
            synchronized (Window.class) { // 不能使用this
                if (ticket > 0) {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":票号:" + ticket--);
                } else {
                    break;
                }
            }
        }
    }
}
窗口1:票号:100
窗口1:票号:99
窗口1:票号:98
窗口1:票号:97
窗口1:票号:96
窗口1:票号:95
窗口1:票号:94
窗口1:票号:93
窗口1:票号:92
窗口1:票号:91
窗口1:票号:90
窗口1:票号:89
窗口1:票号:88
窗口1:票号:87
窗口1:票号:86
窗口1:票号:85
窗口1:票号:84
窗口1:票号:83
窗口1:票号:82
窗口1:票号:81
窗口1:票号:80
窗口1:票号:79
窗口1:票号:78
窗口1:票号:77
窗口1:票号:76
窗口1:票号:75
窗口1:票号:74
窗口1:票号:73
窗口1:票号:72
窗口1:票号:71
窗口1:票号:70
窗口1:票号:69
窗口1:票号:68
窗口1:票号:67
窗口1:票号:66
窗口1:票号:65
窗口1:票号:64
窗口1:票号:63
窗口1:票号:62
窗口1:票号:61
窗口1:票号:60
窗口1:票号:59
窗口1:票号:58
窗口1:票号:57
窗口1:票号:56
窗口1:票号:55
窗口1:票号:54
窗口1:票号:53
窗口1:票号:52
窗口1:票号:51
窗口1:票号:50
窗口1:票号:49
窗口1:票号:48
窗口1:票号:47
窗口1:票号:46
窗口1:票号:45
窗口1:票号:44
窗口1:票号:43
窗口1:票号:42
窗口1:票号:41
窗口1:票号:40
窗口1:票号:39
窗口1:票号:38
窗口1:票号:37
窗口1:票号:36
窗口1:票号:35
窗口1:票号:34
窗口1:票号:33
窗口1:票号:32
窗口1:票号:31
窗口1:票号:30
窗口1:票号:29
窗口1:票号:28
窗口1:票号:27
窗口1:票号:26
窗口1:票号:25
窗口1:票号:24
窗口1:票号:23
窗口1:票号:22
窗口1:票号:21
窗口1:票号:20
窗口1:票号:19
窗口3:票号:18
窗口3:票号:17
窗口3:票号:16
窗口3:票号:15
窗口3:票号:14
窗口3:票号:13
窗口3:票号:12
窗口3:票号:11
窗口3:票号:10
窗口3:票号:9
窗口3:票号:8
窗口3:票号:7
窗口3:票号:6
窗口3:票号:5
窗口3:票号:4
窗口3:票号:3
窗口3:票号:2
窗口3:票号:1

Process finished with exit code 0

3.3 Runnable(同步方法)

如果操作共享数据的代码完整的声明在一个方法中,可以将这个方法声明为同步的

package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) {
        Window window = new Window();
        Thread thread1 = new Thread(window);
        Thread thread2 = new Thread(window);
        Thread thread3 = new Thread(window);
        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread3.setName("窗口3");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

class Window implements Runnable {

    private int ticket = 100;

    @Override
    public void run() {    //public synchronized void run() synchronized包含的同步代码:不能包多也不能包少
        while (true) {
            show();
        }
    }
    private synchronized void show(){ // 同步监视器:this
        if (ticket > 0) {
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":票号:" + ticket--);
        }
    }
}

3.4 Thread(同步方法)

package JavaPackage_13;

public class JavaCode {
    public static void main(String[] args) {
        Window window1 = new Window();
        Window window2 = new Window();
        Window window3 = new Window();
        window1.setName("窗口1");
        window2.setName("窗口2");
        window3.setName("窗口3");
        window1.start();
        window2.start();
        window3.start();
    }
}

class Window extends Thread {

    private static int ticket = 100;

    @Override
    public void run() {
        while (true) {
            show();
        }
    }

    public static synchronized void show(){ // 同步监视器:Window.class
        if (ticket > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":票号:" + ticket--);
        }
    }
}

3.5 Lock解决线程安全问题

package JavaPackage_13;

import java.util.concurrent.locks.ReentrantLock;

public class JavaCode {
    public static void main(String[] args) {
        Window window1 = new Window();
        Window window2 = new Window();
        Window window3 = new Window();
        window1.setName("窗口1");
        window2.setName("窗口2");
        window3.setName("窗口3");
        window1.start();
        window2.start();
        window3.start();
    }
}

class Window extends Thread {

    private static int ticket = 100;
    private static ReentrantLock lock = new ReentrantLock(true); // 公平锁

    @Override
    public void run() {
        while (true) {
            try {
                //调用lock()
                lock.lock();
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":票号:" + ticket--);
                } else {
                    break;
                }
            } finally {
                //调用unlock()
                lock.unlock();
            }
        }
    }
}


请添加图片描述

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

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

相关文章

Mybatis源码(三)如何操作数据库

前言 接着environmentElement获取数据源信息后&#xff0c;同级执行代码的mappersElement。里面参杂了mybatis缓存。 Mybatis源码&#xff08;三&#xff09;如何操作数据库 MyBatis源码&#xff08;二&#xff09;如何执行sql Mybatis源码&#xff08;一&#xff09;获取数…

从咖啡馆到世界,共赴下一个十年 |写在 EMQX 开源十周年

十年前,在 2012 年 12 月 17 日,源于个人对 Erlang、MQTT 和开源的热爱,EMQX 诞生于一家咖啡馆并作为开源项目在 GitHub 上发布了初次提交。十年后的今天,EMQX 已成长为 Erlang 生态中最具影响力的物联网开源基础软件项目,作为全球最具扩展性的 MQTT 消息服务器在物联网、工业互…

【Java开发】Spring Cloud 02 :微服务项目介绍及开发环境

了解完 Spring Cloud 的发展背景以及各个组件库后&#xff0c;在敲代码前&#xff0c;本章节会聊一聊优惠券平台项目的整体功能和模块&#xff0c;以及每个功能点的技术选型和背后的依据&#xff0c;最后讲解下搭建项目所需的开发环境~ 目录 1 优惠券平台项目 1.1 项目介绍 …

[Linux安装软件详解系列]05 安装ElasticSearch和IK分词器

目录1、安装ElasticSearch2、安装IK分词器操作系统&#xff1a;Anolis OS 8.6 RHCK 64位、jdk1.8。ElasticSearch&#xff1a;v6.8.6下载文件&#xff1a; ElasticSearch v6.8.6&#xff1a; https://elastic.co/downloads/elasticsearch IK分词器 v6.8.6&#xff1a;https://g…

脚本-简单脚本

脚本执行顺序 默认脚本是无序执行&#xff0c;也就是哪个脚本先执行&#xff0c;哪个脚本后执行是未知的。 也可以手动指定执行顺序&#xff0c; 在如上图所示中&#xff0c;可以点击 加号 按钮&#xff0c;然后添加脚本的顺序&#xff0c;数值越大&#xff0c;执行顺序越靠后…

为什么团队执行力差,管理者应该如何解决?

没有执行力&#xff0c;一切都是空谈。团队执行力差可能是这些原因&#xff1a; 1、目标不明确&#xff0c;项目方向不清晰。 2、责任不清&#xff0c;不知道干啥&#xff0c;也不知道为什么而干。 3、技能不熟练&#xff0c;没有明确的完成标准。 4、分配任务&#xff0c;…

【JavaScript】飞机大战

文章目录一、效果演示设计思路二、鼠标版飞机大战代码展示1.HTML结构代码2.CSS样式代码3.JavaScript代码js.js文件plane.js文件三、键盘版飞机大战代码展示1.HTML结构代码2.CSS样式代码3.JavaScript代码四、代码资源分享一、效果演示 利用html&#xff0c;css&#xff0c;js制…

华为云服务器上部署war包(虚拟机也同样适用)

目录linux部署war包安装jdk关闭防火墙简单粗暴&#xff08;推荐虚拟机使用&#xff09;复杂但安全&#xff08;推荐服务器使用&#xff09;安装tomcat部署war包linux部署war包 安装jdk 执行命令查看可安装java版本 yum -y list java*执行命令安装jdk8 yum install -y java-…

12. 爬虫训练场项目,jinja2 模板继承,项目继续迭代

本篇博客我们将前端模板的通用部分进行抽离&#xff0c;便于整理管理&#xff0c;使用的是 jinja2 中模板继承相关技术。 文章目录Flask 模板引擎块&#xff08;Block&#xff09;更细的块拆解完善 general 目录和 school 目录 HTML 文件宏&#xff08;Macro&#xff09;Flask …

章节六:RASA NLU组件介绍--特征生成器

目录一、前言二、特征生成器MitieFeaturizerSpacyFeaturizerConveRTFeaturizerLanguageModelFeaturizerRegexFeaturizerCountVectorsFeaturizerLexicalSyntacticFeaturizer一、前言 RASA在处理对话时&#xff0c;整体流程是pipeline结构&#xff0c;自然语言理解&#xff08;N…

SpringBoot操作Redis

目录 1.IDE创建一个maven项目 2、 添加redis启动器 3.修改配置文件application.properties 4.在测试类中测试 SpringBoot操作Hash&#xff08;哈希&#xff09; SpringBoot操作List集合类型 SpringBoot操作Set集合类型 SpringBoot操作ZSet集合类型 1.IDE创建一个maven项…

dubbo(尚硅谷)学习笔记2

我们现在来做dubbo和springboot整合&#xff1a; 我们先来创建一个springboot项目&#xff1a; 然后把serviceimpl层拷贝过来。 因为我们这个也需要用到公用接口和实体类&#xff0c;所以还是需要导入一下这个依赖&#xff1a; 同样的我们也需要创建一个服务的消费者&#xf…

设计模式之美总结(行为型篇)

title: 设计模式之美总结&#xff08;行为型篇&#xff09; date: 2022-12-26 17:25:29 tags: 设计模式 categories:设计模式 cover: https://cover.png feature: false 文章目录1. 观察者/发布订阅模式&#xff08;Observer Design Pattern/Publish-Subscribe Design Pattern…

Unity2D像素游戏开发——Aseprite简单人物绘画+动画制作导出精灵表示例

目录 前言 什么是帧&#xff1f; 什么是Aseprite&#xff1f; 运行环境 正文 示例&#xff1a;绘制人物 制作多帧动画 微调 导出精灵表 总结 作品欣赏 附一个下载链接&#xff1a; 前言 什么是帧&#xff1f; 我们看到的动画都是由一张张图片连续播放而成的&#…

scipy

scipy.interpolate插值方法 import numpy as np def func(x, y):return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2grid_x, grid_y np.mgrid[0:1:100j, 0:1:200j]rng np.random.default_rng() points rng.random((1000, 2)) values func(points[:,0], points[:…

高颜值蓝牙耳机有哪些?音质好颜值高的蓝牙耳机推荐

喜欢安静的人们&#xff0c;相信都会有一副蓝牙耳机吧&#xff0c;作为我们生活当中必不可少的数码产品&#xff0c;除了手机以外&#xff0c;蓝牙耳机几乎也是使用率很高的&#xff0c;它通过蓝牙连接&#xff0c;非常方便&#xff0c;下面是小编精心挑选的四款蓝牙耳机。 一…

告别“限速”,个人网盘进入云时代

配图来自Canva可画 在数字经济广泛渗透的条件下&#xff0c;个人网盘市场也得到了长足发展。而在5G和AI的加持下&#xff0c;个人网盘不断进行技术融合和迭代&#xff0c;云盘已然成为互联网用户以及智能设备存储的基本服务&#xff0c;而其应用场景也顺理成章地开始向各个细分…

window11 node.js 安装与下载

最近电脑莫名其妙的被一些恶意流氓软件捆绑了&#xff0c;今天我直接给恢复出厂设置了。顺便记录一下软件的安装步骤。 1. 先去官网下载 官网地址 ① 进入到官网后如下图所示 ②根据自己电脑选择合适的版本下载&#xff08;我是wiindows 64位 &#xff09; ③ 双击安装包点击…

道路交通警示牌数据集以及训练好的YOLO模型权重文件

道路交通警示牌yolo模型1.交通标志数据集的介绍2.训练出权重文件1.交通标志数据集的介绍 交通标志&#xff08;国外的交通标志&#xff09;数据集是经过标注过的数据集&#xff0c;包括77个类别&#xff1b;标注类别如下&#xff1a; ‘200m’, ‘50-100m’, ‘Ahead-Left’, …

如何写好一份数据分析报告?

数据分析报表怎么做&#xff1f;这是一个很笼统的问题&#xff0c;所以这篇尝试从数据分析报表的3个方面来说下&#xff0c;准备了3天&#xff0c;内容较长&#xff0c;心急的小伙伴先看索引&#xff1a; 数据分析报表的原则数据分析报表的数据来源数据分析报表的可视化展示 0…