d19(175-183)-勇敢开始Java,咖啡拯救人生

目录

多线程

多线程的创建方式一:继承Thread类

多线程的创建方式二:实现Runnable接口

匿名内部类写法

多线程的创建方式三:实现Callable接口、FutureTask类

Thread常用方法

线程安全

方法一:同步代码块

方法二:同步方法

方法三:Lock锁

线程通信

线程池

创建线程池

使用ThreadPoolExecutor

线程池处理Runnable任务

拒绝策略

线程池处理Callable任务

Executors工具类实现线程池(白雪

并发、并行(多线程是并发和并行同时进行的

线程的生命周期

悲观锁 乐观锁


多线程

线程Thread是一个程序内部的一条执行流程

多线程的创建方式一:继承Thread类

编码简单,但线程类已继承Thread,无法继承其他类,不利于功能扩展

注意:

1.启动线程需调用start方法(多线程,向CPU注册该线程),而不是run方法(只是普通方法调用,仍是单线程)

2.主线程的任务不要放在子线程之前

多线程的创建方式二:实现Runnable接口

详细实现:

优点是任务类只是实现接口,还可以继续继承其他类,实现其他接口,扩展性强

缺点是多了一个runnable对象

匿名内部类写法

多线程的创建方式三:实现Callable接口、FutureTask类

前两种线程创建方式,重写的run方法均不能直接返回结果

优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强;可以在线程执行完毕后去获取线程执行的结果
缺点:编码复杂一点。

Thread常用方法

在线程start前给它取名字哈,或者创建的时候就起名哈

线程安全

多个线程在同时操作同一个共享资源时,可能会出现业务安全问题

就是操作系统里学的线程那块,什么读者写者、哲学家就餐什么的

方法一:同步代码块

ctrl + alt +t 9synchronized

锁是“黑马”,实际上换成什么都行,但也会有一个问题,那就是所有人都用一把锁,实际上可能取钱操作只需要按账户锁

所以应该用this作为锁

synchronized(this){}

this刚好代表共享资源

静态方法用类名.class作为锁

方法二:同步方法

同步代码块锁的范围小一点,性能更好,同步方法锁的范围更大,性能差一些[这点性能差距现在几乎可以忽略了]

同步方法可读性更好

方法三:Lock锁

可以创建出锁对象,进行加锁解锁,更灵活方便强大

Lock是接口,不能直接实例化,可以采用它的实现类ReentrantLock

比如每个账户都需要一个锁,所以应该把锁放在创建账户对象里

1.建议用final修饰

2.保证中间出问题,也要能解锁,所以用try-catch-finally,finally解锁

线程通信

生产者消费者haha

上述方法应该使用当前同步锁对象进行调用。

线程池

线程池就是一个可以复用线程的技术。

用户每发起一个请求,后台就需要创建一个新线程来处理,新任务来了又要创建新线程处理的,而建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能

工作线程WorkThread和任务队列WorkQueue,控制线程数量,复用线程处理任务;同时也控制任务数量,避免系统资源耗尽

任务其实是对象,必须实现了Runnable或Callable接口

创建线程池

接口ExecutorService,用它的实现类ThreadPoolExecutor

使用ThreadPoolExecutor

线程池的注意事项
1、临时线程什么时候创建?
新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程。
2、什么时候会开始拒绝新任务?
核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始拒绝任务。

线程池处理Runnable任务

拒绝策略

线程池处理Callable任务

Executors工具类实现线程池(白雪

是一个线程池的工具类,提供了很多静态方法用于返回不同特点的线程池对象。

注意 :这些方法的底层,都是通过线程池的实现类ThreadPoolExecutor创建的线程池对象

计算密集型的任务:核心线程数量=CPU的核数+1
IO密集型的任务:核心线程数量=CPU核数*2

大型并发系统环境中使用Executors如果不注意可能会出现系统风险

并发、并行(多线程是并发和并行同时进行的

正在运行的程序(软件)就是一个独立的进程。
线程是属于进程的,一个进程中可以同时运行很多个线程。
进程中的多个线程其实是并发和并行执行的。

并发的含义
进程中的线程是由CPU负责调度执行的,但CPU能同时处理线程的数量有限,为了保证全部线程都能往前执行CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们的感觉这些线程在同时执行,这就是并发。

并行的理解
在同一个时刻上,同时有多个线程在被CPU调度执行。

线程的生命周期

悲观锁 乐观锁

什么是悲观锁,乐观锁,举例和适用场景,悲观锁实现_乐观锁和悲观锁的应用场景,怎么实现-CSDN博客

Demo.java

package cn.ptz.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Demo1 {
    public static void main(String[] args) throws Exception {
        // two people give out the gifts(100
        List<String> gift = new ArrayList<>();
        String[] names = {"1gift","2gift","3gift","4gift","5gift","6gift"};
        Random r = new Random();
        for (int i = 0; i < 100; i++) {
            gift.add(names[r.nextInt(names.length)] + (i + 1));
        }
        System.out.println(gift);

        // 线程类 -> 线程对象
        SendThread a = new SendThread(gift,"aa");
        a.start();
        SendThread b = new SendThread(gift,"bb");
        b.start();
        a.join(); // 等待线程结束
        b.join();
        System.out.println(a.getCount());
        System.out.println(b.getCount());
    }
}

SendThread.java

package cn.ptz.thread;

import java.util.List;
import java.util.Random;

public class SendThread extends Thread {
    private List<String> gift;
    private int count;

    public SendThread(List<String> gift, String name) {
        super(name);
        this.gift = gift;
    }

    @Override
    public void run() {
        Random r = new Random();
        String name = Thread.currentThread().getName();
        // 发礼物
        // 线程安全
        // synchronized (this){} 这个锁不合适,因为两个线程的this不一样,没锁住
        while (true) {
            synchronized (gift){
                if (gift.size() < 10){
                    break;
                }
                String rs = gift.remove(r.nextInt(gift.size()));
                System.out.println(name + ":" + rs);
                count++;
            }
        }
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

  • 41
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ESP32-WROOM-32D是一款集成了WiFi和蓝牙功能的低功耗芯片模块,其引脚分布和功能如下: 1. GND(引脚1):地,用于提供模块的电源接地。 2. 3.3V(引脚2):电源输入,用于接入3.3V的电源供应。 3. EN(引脚3):模块使能引脚,高电平使模块工作,低电平使其进入待机模式。 4. VP(引脚4):读视频数据引脚(未使用)。 5. D2(引脚5):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 6. D3(引脚6):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 7. CMD(引脚7):SPI总线的命令线。 8. CLK(引脚8):SPI总线的时钟线。 9. SD0(引脚9):SPI总线的数据线。 10. SD1(引脚10):SPI总线的数据线。 11. SD2(引脚11):SPI总线的数据线。 12. SD3(引脚12):SPI总线的数据线。 13. GND(引脚13):地。 14. VDD_SDIO(引脚14):SDIO卡和WiFi模块的电源引脚。 15. MTDO(引脚15):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 16. MTCK(引脚16):调试时的串行TAP控制引脚。 17. MTDI(引脚17):进入Flash Boot模式的引脚。 18. MTMS(引脚18):调试时的串行TAP数据引脚。 19. TXD0(引脚19):UART0的发送引脚。 20. RXD0(引脚20):UART0的接收引脚。 21. TXD1(引脚21):UART1的发送引脚。 22. RXD1(引脚22):UART1的接收引脚。 23. D23(引脚23):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 24. D22(引脚24):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 25. D21(引脚25):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 26. D19(引脚26):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 27. D18(引脚27):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 28. D5(引脚28):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 29. D17(引脚29):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 30. D16(引脚30):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 31. D4(引脚31):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 32. D0(引脚32):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 33. D2(引脚33):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 34. D15(引脚34):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 35. D13(引脚35):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 36. D12(引脚36):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 37. D14(引脚37):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 38. D27(引脚38):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 39. D26(引脚39):GPIO引脚,可以用作通用输入/输出或特定功能的引脚。 通过连接与这些引脚相应的电路,我们可以实现不同的功能,如UART通信、SPI通信、控制外部模块的输入输出等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值