Java学习之路 —— 多线程

news2024/11/25 14:35:15

文章目录

  • 1. 线程创建方式
    • 1.1 继承Thread
    • 1.2 声明一个实现Runnable接口的类
    • 1.3 利用Callable接口、FutureTask类来实现
  • 2. 线程同步
    • 2.1 同步代码块
    • 2.2 同步方法
    • 2.3 Lock锁
  • 3. 线程同步
  • 4. 线程池

1. 线程创建方式

1.1 继承Thread

定义子类,继承Thread,创建对象,并调用start启动线程

  • 优点:编码简单
  • 缺点:线程类已经继承Thread,无法继承其他类,不利于功能的扩展
public class Main {
    // main方法是有一条默认的主线程执行的
    public static void main(String[] args) {
        // 1. 创建线程类的对象,代表一个线程
        Thread t = new MyThread();
        // 2. 启动线程
        t.start();
        for (int i = 0; i < 10000; i++) {
            System.out.println("主线程输出:" + i);
        }
    }
}

注意,是调用Thread的start方法,而不是run方法!!!

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println("子线程输出:" + i);
        }
        super.run();
    }
}

1.2 声明一个实现Runnable接口的类

  • 优点:只是实现了一个接口,还可以继承一个类,实现其他接口,扩展性强
  • 缺点:需要多创建一个Runnable对象
class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            System.out.println("子线程输出:" + i);
        }
    }
}

static void test_Runnable() {
//        Runnable target = new MyRunnable(); // 任务对象(不是线程对象)
//        new Thread(target).start();
        // lambda
        new Thread(() -> {
            for (int i = 0; i < 10000; i++) {
                System.out.println("子线程输出:" + i);
            }
        for (int i = 0; i < 10; i++) {
            System.out.println("主线程输出:" + i);
        }
    }

1.3 利用Callable接口、FutureTask类来实现

  • 优点:可以返回线程执行完后的结果
  • 缺点:编码复杂
    在这里插入图片描述
class MyCallable implements Callable<String> {
    int n;
    public MyCallable(int n) {
        this.n = n;
    }
    @Override
    public String call() throws Exception {
        // 描述线程的任务,返回线程执行后的结果
        // 求1-n的和
        int sum = 0;
        for(int i = 1; i <= n; i++)
            sum += n;
        return "1~n的总和是:" + sum;
    }
}
static void test_Callble() {
        // 1. 创建Callable对象
        MyCallable call = new MyCallable(50);
        // 2. 把Callable对象封装成FutureTask对象
            // 1. 是一个任务对象,实现了Runnable对象
            // 2. 可以在线程执行完后,调用get方法获取
        FutureTask<String> f1 = new FutureTask<>(call);
        new Thread(f1).start();
        for (int i = 0; i < 10; i++) {
            System.out.println("主线程输出:" + i);
        }
        // 获取线程执行完毕后的结果
        String s = null;
        try {
            // 会等到线程执行完毕,这行代码再执行
            s = f1.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(s);

    }

我发现啊,Java的多线程和C++的多线程不一样的点是,Java中创建子线程,如果主线程先执行完了,子线程没有执行完,子线程会继续执行;但是C++会被终止。

不过join方法都有着相同的用处,那就是阻塞主线程,等待线程执行完毕后,再执行主线程后面的代码。

2. 线程同步

2.1 同步代码块

synchronized(同步锁) {
	访问共享资源的核心代码
}

这个同步锁是一个字符串也可以(双引号在内存中存在常量区,只有一份),只要是一个唯一对象即可 。
但最好是用共享资源作为锁,比如说this

如果要调用静态方法,同步锁采用类名.class,锁住整个class。

2.2 同步方法

把访问共享资源的核心方法上锁,保证线程安全。这样能保证一个对象中,只有一个方法在执行,其他方法都无法执行。

修饰符 synchronized 返回值类型 方法名(形参列表){
	操作共享资源得到代码
}

2.3 Lock锁

Lock是一个接口类,可以用实现类ReentrantLock来实例化一个锁,来使用。

Lock lk = new ReentrantLock();
lk.lock();
lk.unlock();

3. 线程同步

来了来了,条件遍历来了。注意,一定要和锁搭配使用。
在这里插入图片描述
来一个经典的例子吧,2个线程交替打印A和B

package TestDemo;

// 2个线程交替打印A和B10次
public class Test2 {
    public static int count;
    static final Object lock = new Object(); // 锁
    public static void main(String[] args){
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                synchronized (lock) {
                    System.out.println(Thread.currentThread().getName() + "打印A");
                    lock.notify();
                    try {
                        if(i < 9)
                            lock.wait();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "A线程");

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                synchronized (lock) {
                    System.out.println(Thread.currentThread().getName() + "打印B");
                    lock.notify();
                    try {
                        if(i < 9)
                            lock.wait();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "B线程");
        t1.start();
        t2.start();
    }
}

4. 线程池

JDK5提供了代表线程池的接口:ExecutorService。比较常用的实现类是ThreadPoolExecutor

  • public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
    • corePoolSize:指定线程池的核心线程数量
    • maximumPoolSize:指定线程池的最大线程数量
    • keepAliveTime:指定临时线程的存活时间
    • unit:指定临时线程存货的时间单位
    • workQueue:指定线程池的任务队列
    • threadFactory:指定线程池的任务工厂
    • handler:指定线程池的拒绝策略(任务队列满了后,新任务来了怎么处理)

在这里插入图片描述线程池默认是不会死亡的,除非调用shutdown(),或者shutdownNow()

  1. 临时线程什么时候创建?
    新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程,去执行新任务,而不是任务队列的任务(插队)。
  2. 什么时候会开始拒绝新任务?
    核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始拒绝任务。

Executors
是线程池的一个工具类,提供了很多静态方法用于返回不同特点的线程池对象。
在这里插入图片描述

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

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

相关文章

Vue指令修饰符、v-bind、v-model、computed计算属性、watch侦听器

前言 持续学习总结输出中&#xff0c;Vue指令修饰符、v-bind、v-model、computed计算属性、watch侦听器 一、指令修饰符 1.什么是指令修饰符&#xff1f; 所谓指令修饰符就是通过“.”指明一些指令后缀 &#xff0c;不同的后缀封装了不同的处理操作 —> 简化代码 2.按键…

玩具、儿童用品、儿童服装上亚马逊TEMU平台CPC认证办理

CPC认证是Childrens Product Certificate的简称&#xff0c;即儿童产品证书。它是美国强制性法规CPSIA要求的一部分&#xff0c;该法规主要针对12岁及以下儿童使用的产品&#xff0c;如玩具、儿童用品、儿童服装等。 一、儿童小汽车CPC测试项目可能会因产品标准和法规的不同而…

开关电源测试之输出暂态响应测试标准及方法详解

暂态响应是指在接收到输入信号后&#xff0c;输出信号在短时间内产生的变化。开关电源输出暂态响应测试是为了检测输出负载快速变化时&#xff0c;输出电压跟随变动的稳定性。 开关电源输出暂态响应怎么测试&#xff1f; 测试目的&#xff1a;测试S.M.P.S.输出负载快速变化时&a…

中小型企业内网搭建

某中小型公司客户提出网络比较单一整体都在一个大的广播域中&#xff0c;AP无线的SSID有很多个&#xff0c;包括一些小的无线路由器散发出来的信号&#xff0c;用起来网络不太稳定&#xff0c;并且AP的SSID要分开&#xff0c;办公室只有单个SSID&#xff0c;不允许出现其他的&a…

【Ubuntu】设置永不息屏与安装 dconf-editor

方式一、GUI界面进行设置 No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.6 LTS Release: 20.04 Codename: focal打开 Ubuntu 桌面环境的设置菜单。你可以通过点击屏幕右上角的系统菜单&#xff0c;然后选择设置。在设置菜单中&#xff0c;…

休闲机动滑板车和便携式自行车ASTMF2641-23测试标准如何办理?

领先的行业资讯 近日&#xff0c;美国材料实验协会ASTM发布了2023版“休闲机动滑板车和便携式自行车的消费者安全规范” ASTM F2641-23&#xff0c;取代上一版本ASTM F2641-08 (2015)。 该规范是基于目前最先进的娱乐电动滑板车和迷你摩托车技术水平&#xff0c;旨在涵盖产品的…

Win10专业版如何重装-Win10专业版重装系统教程

Win10专业版如何重装&#xff1f;Win10专业版系统能够用户带来丰富的功能服务&#xff0c;用户操作需求轻松得到满足。如果我们在Win10专业版电脑中&#xff0c;遇到了系统问题&#xff0c;这时候可以考虑重新安装Win10专业版系统&#xff0c;从而解决系统出现的问题。下面小编…

全球温度数据下载

1.全球年平均温度下载https://www.ncei.noaa.gov/data/global-summary-of-the-year/archive/ 2.全球月平均气温下载https://www.ncei.noaa.gov/data/global-summary-of-the-month/archive/ 3.全球日平均气温下载https://www.ncei.noaa.gov/data/global-summary-of-the-day/ar…

Bard似乎在胡扯的路上飞速狂奔?

Bard似乎在胡扯的路上飞速狂奔&#xff1f;连最简单的问题都以胡扯来回答&#xff1f;

全网火爆,接口自动化测试框架-fixture函数使用,一篇打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 setup和teardown能…

医疗项目的需求分析以及开发流程

一.项目的背景以及需求 1.项目背景 1.政策层面来看&#xff0c;近年来我国政府相关部门陆续颁发了支持数字医疗行业发展的相关政策&#xff0c;“互联网医疗”政策逐渐明确完善&#xff0c;为数字医疗行业发展提供支持&#xff0c;行业迎来政策福利期。 其次&#xff0c;从经济…

echarts 数据过多时展示滚动条

【echarts官网地址&#xff1a;Documentation - Apache ECharts】 针对echarts图数据过多的情况&#xff0c;echarts官网有专门的属性dataZoom&#xff1a;用于区域缩放&#xff0c;从而能自由关注细节的数据信息&#xff0c;或者概览数据整体&#xff0c;或者去除离群点的影响…

超全整理,Pytest自动化测试框架-多进程(pytest-xdist)运行总结...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 平常我们功能测试…

在誉天学习华为认证,有真机吗

通过培训机构学习华为认证&#xff0c;特别是在HCIE的课程学习中&#xff0c;很多人关心的就是培训机构是否有真机能够进行华为认证的相关实验&#xff0c;今天我们一起来看看&#xff0c;在誉天学习华为认证&#xff0c;有真机吗&#xff1f; 誉天总部数据中心机房和誉天总部一…

获取微信小程序二维码

可直接通过微信扫描小程序二维码直接进入小程序&#xff0c;可用在分享推广业务。 目录 Curl请求方法 获取小程序token 获取小程序二维码 参数说明 注意 请求结果 Curl请求方法 需要请求微信小程序的API接口&#xff0c;封装好curl请求方法。 代码如下&#xff1a; /*…

西浦成立产业家学院破解 “产业级” 问题!AMT企源成首批合作机构

在推动高质量发展的国家战略背景下&#xff0c;从集成电路到人工智能&#xff0c;从新能源到绿色低碳&#xff0c;从健康养老到数字文创&#xff0c;无论国家还是区域都面临着产业转型升级或突破创新的发展需求&#xff0c; 这些 “产业级” 问题的难度远非单个企业层面问题可比…

C++泛型编程——模板(初识)

C泛型编程——模板&#xff08;初识&#xff09; 文章目录 C泛型编程——模板&#xff08;初识&#xff09;1. 泛型编程的概念2. 模板2.1 模板格式2.2 函数模板2.3 函数模板的实例化2.3.1 隐式&#xff08;推演&#xff09;实例化2.3.2 显式实例化 2.3 类模板3. 模板的本质 本章…

【教学类-36】八等分格子-A4竖版-4条(制作皇冠、戒指)

背景需求&#xff1a; 最近在大四班孩子中间普及铅画纸制作“方盒”的活动&#xff0c;目前进展到使用三条8等分的长条纸&#xff0c;制作一个“坚硬的、不漏底”的方盒。 实验后&#xff0c;我想试试如果缩小纸条长宽&#xff0c;是不是可以做“迷你”纸盒。 目的&#xff…

为什么别人年薪30W+?同样为测试人,“我“的测试之路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、软件测试员&am…

可变形卷积 DeformConv2d

可变性卷积 前言为什么要用DConv普通卷积和与可变形卷积计算过程普通卷积计算过程Pytorch官方API可变形卷积计算过程 参考资源 前言 可变形卷积即DCN&#xff08;缩写取自Deformable ConvNets&#xff09;提出于ICCV 2017的paper: Deformable Convolutional Networks 论文pape…