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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值