线程的创建和使用(一)

1、线程

1.1、线程的概念

一个线程就是一个 "执行流". 每个线程之间都可以按照顺讯执行自己的代码. 多个线程之间 "同时" 执行着多份代码.

1.2、创建线程

方法一:继承Thread类


public class Exe_01 {
    public static void main(String[] args) {
        //实例化线程对象
        MyThread01 myThread01=new MyThread01();
        //运行这个线程
        myThread01.start();
    }
}

//通过继承Thread类的方式来创建一个线程
class MyThread01 extends Thread{
    @Override
    public void run() {
        System.out.println("Hello 鸡你太美!!");
    }
}

运行结果:

 

 观察线程调度:


public class Exe_02 {
    public static void main(String[] args) {
        //实例化线程对象
        MyThread02 myThread02=new MyThread02();
        //真正去操作系统中申请线程并参与CPU调度
        myThread02.start();

        //在主线程也做一个死循环打印
        while(true){
            System.out.println("唱跳,rap,篮球");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class MyThread02 extends Thread{
    //定义线程要执行的任务
    @Override
    public void run() {
        //在一个死循环中做打印
        while(true){
            System.out.println("哎呦,你干嘛!!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果:

 

 方法二:实现Runnable接口


public class Exe_03 {
    //通过实现Runnable的方式创建线程
    public static void main(String[] args) {
        //实例化自定义线程类
        MyRunnable runnable=new MyRunnable();
        //通过Thread的构造方法把Runnable作为参数传入
        Thread thread=new Thread(runnable);
        //启动线程才是真正意义上的创建系统线程,参与CPU调度
        thread.start();
    }
}

//实现Runnable接口
class MyRunnable implements Runnable{
    //定义线程要执行的任务
    @Override
    public void run() {
        while(true){
            System.out.println("年轻人,耗子为汁+1");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果:

 

由我来给大家利用线程制作一个蔡徐坤经典名场面


public class Exe_04 {
    public static void main(String[] args) {
        //练习生任务
        Runnable01 runnable01=new Runnable01();
        //第一步给大家打个招呼
        Thread t1=new Thread(runnable01);
        t1.start();

        //表演任务
        Runnable02 runnable02=new Runnable02();
        //第二步给介绍鸽鸽的特长
        Thread t2=new Thread(runnable02);
        t2.start();

        //音乐走你
        Runnable03 runnable03=new Runnable03();
        //第三步showTime
        Thread t3=new Thread(runnable03);
        t3.start();
    }
}

//创建Runnable类
//定义一个练习两年半练习生的任务
class Runnable01 implements Runnable{
    @Override
    public void run() {
        while (true) {
            System.out.println("全明星制作人们,大家好,我是一个练习时长两年半的个人练习生蔡徐坤");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//定义一个小黑子的任务
class Runnable02 implements Runnable{
    @Override
    public void run() {
        while (true) {
            System.out.println("喜欢唱、条、rap、篮球");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//点一首music送给鸽鸽
class  Runnable03 implements Runnable{
    @Override
    public void run() {
        while (true) {
            System.out.println("music");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果:

通过Thread类的匿名内部类的方式创建线程

/*
通过Thread类的匿名内部类的方式创建线程
 */
public class Exe_5 {
    public static void main(String[] args) {
        Thread thread=new Thread(){
            public void run(){
                while (true) {
                    System.out.println("通过创建Thread类的匿名内部类的方式创建线程");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        thread.start();
    }
}

运行结果:

 通过创建实现了Runnable接口的匿名内部类的方式创建线程

/*
通过创建实现了Runnable接口的匿名内部类的方式创建线程
 */
public class Exe_06 {
    public static void main(String[] args) {
        Thread thread=new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while(true) {
                    System.out.println("通过创建实现了Runnable接口的匿名内部类的方式创建线程" + count++);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });
        //启动线程
        thread.start();
    }
}

对比:上面两种方法

继承Thread,直接使用this就表示当前线程的引用。

实现Runnable接口,this表示的是MyRunnbale的引用,需要使用Thread类来调用

 3、通过lambda的方式创建线程


public class Exe_07 {
    public static void main(String[] args) {
        Thread thread=new Thread(()-> {
            int count=0;
            while(true){
                count++;
                System.out.println("通过lambda表达式的方式创建一个线程"+count);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        //启动线程
        thread.start();
    }
}

 2、多线程的优势

多线程的优势--增加运行速度

多线程就是为了能够充分的利用CPU的资源,提升程序运行效率。

需求场景:

分别对两个变量做累加100亿次操作

一种是单线程执行,一种是两条线程并发操作。

/*多线程的优势-增加运行速度
分别对两个变量做100亿次累加操作
 */
public class Exe_08 {
    private static long count=10_0000_0000l;
    public static void main(String[] args) {
        //串行方式
        serial();
        //并行方式
        concurrency();
    }

    private static void concurrency() {
        //记录开始时间
        long begin=System.currentTimeMillis();
        //创建线程,在单个线程中执行对一个变量的累加
        Thread t1=new Thread(()->{
            long a=0l;
            for (int i = 0; i < count; i++) {
                a++;
            }
        });
        Thread t2=new Thread(()->{
            long b=0l;
            for (int i = 0; i < count; i++) {
                b++;
            }
        });
        //启动线程
        t1.start();
        t2.start();
        //等待
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("并行操作用时:"+(end-begin)+"ms.");
    }

    private static void serial(){
        //记录开始时间
        long begin=System.currentTimeMillis();
        long a=0l;
        //对变量进行累加
        for (int i = 0; i < count; i++) {
            a++;
        }
        long b=0l;
        for (int i = 0; i < count; i++) {
            b++;
        }
        //累加完成之后记录结束时间
        long end=System.currentTimeMillis();
        System.out.println("串行操作用时:"+(end-begin)+"ms.");
    }
}

运行结果:

结论:多线程的使用可以明显的提高程序的运行效率,充分利用CPU的资源。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[论文阅读笔记76]GPT Understands, Too(P-tuning)

1. 基本信息 题目论文作者与单位来源年份GPT Understands, Too清华大学 Citations, References 论文链接&#xff1a;https://arxiv.org/pdf/2103.10385.pdf 论文代码&#xff1a; 2. 要点 研究主题问题背景核心方法流程亮点数据集结论论文类型关键字微调大模型采用传统微…

什么是HMI和SCADA?两者有什么区别

前言 几十年来&#xff0c;工业控制系统在工业自动化中发挥了重要作用&#xff0c;它允许过程制造商从生产车间采集、分析、处理数据。 在当今瞬息万变的工业环境中&#xff0c;制造商和公用事业公司必须采用现代HMI/SCADA和数字化转型&#xff0c;以跟上变化的步伐&#xff0…

Unity制作二次元卡通渲染角色材质——5、脸部的特殊处理

Unity制作二次元材质角色 回到目录 大家好&#xff0c;我是阿赵。 这里继续讲二次元角色材质的制作。这次是讲头部的做法。 1、脸部 之前在分析资源的时候&#xff0c;其实已经发现了这个模型的脸部法线有问题&#xff0c;导致在做光照模型的时候&#xff0c;脸部很奇怪。 把f…

NLP:词义分布的空间维度——从文本符号到词向量表征

自然语言处理的前提是文本表示&#xff08;Representation&#xff09;&#xff0c;即如何将人类符号化的文本转换成 计算机所能“理解”的表征形式。早期的自然语言表征主要采用离散表示。近年来&#xff0c;随着深度 学习的不断发展&#xff0c;基于神经网络的分布式词向量技…

概率论:方差、标准差、协方差、皮尔逊相关系数、线性相关

方差和标准差&#xff1a; 一个随机变量&#xff0c;的值的变化程度可以用方差计算&#xff1a; &#xff1b;其中 是期望。 另外一种等价表达式&#xff1a; 其中为均值&#xff0c;N为总体例数 我们举个例子&#xff1a; 服从均一分布&#xff0c;取值为0.1&#xff0c;0…

SpringSecurity多源认证之全部交给spring容器

文章目录 一. 前言二. 配置流程2.1 SecurityConfig.class2.2 JwtAuthenticationTokenFilter2.3 AuthenticationManagerProcessingFilter 疑问 一. 前言 相关文章: 认证/支付/优惠劵策略模式-security多源认证 这篇文章没有将自定义的认证管理器注入容器. spring-security2.6.…

CSS基础学习--7 fonts字体

一、CSS 字体 CSS字体属性定义字体系列&#xff0c;加粗&#xff0c;大小&#xff0c;文字样式。 二、字体系列 font-family 属性设置文本的字体系列 font-family 属性应该设置几个字体名称作为一种"后备"机制&#xff0c;如果浏览器不支持第一种字体&#xff0c;…

C++入门前必看,超详细

目录 前言 一.C的关键字 二.命名空间 2.1命名空间定义 2.2命名空间的使用 三.C的输入及输出 四.缺省参数 4.1概念 4.2缺省参数分类 4.3缺省参数的注意点 五.引用 5.1 概念 5.2引用的特性 六.内联函数 6.1概念 6.2内联函数的特性 七.auto 7.1auto概念 7.2auto的…

Unity入门5——Camera

一、参数面板 二、参数介绍 1. Clear Flags&#xff1a;清除背景 Skybox&#xff1a;天空盒背景&#xff08;通常用来做 3D 游戏&#xff09; Solid Color&#xff1a;使用 Background 颜色填充&#xff08;通常设置为全黑或全白&#xff0c;2D 使用&#xff09; Depth Only&am…

APP测试面试题快问快答(四)

16.App测试的实时日志如何获取&#xff1f; 考察点&#xff1a;是否有移动app测试的日志获取相关经验 一般可以通过以下方式获取&#xff1a; 1.可以使用adb命令&#xff1a;adb logcat | findstr "com.sankuai.meituan" >d:\test.txt 2.用ddms抓取&#xff0…

Postgresql源码(106)Generic Plan与Custom Plan的区别(以分区表为例)

相关&#xff1a; 《Postgresql源码&#xff08;105&#xff09;分区表剪枝代码分析》 《Postgresql源码&#xff08;106&#xff09;Generic Plan与Custom Plan的区别&#xff08;以分区表为例&#xff09;》 实例 CREATE TABLE measurement (city_id int not null,l…

FFmpeg音视频处理工具介绍及应用

1 FFmpeg介绍 FFmpeg项目由 Fabrice Bellard在2000年创立。到目前为止&#xff0c;FFmpeg项目的开发者仍然与VLC、MPV、dav1d、x264等多媒体开源项目有着广泛的重叠。Ffmpeg&#xff08;FastForward Mpeg&#xff09;是一款遵循GPL的开源软件&#xff0c;在音视频处理方面表现…

UDS关于0x37服务退出传输学习笔记

1.服务说明 客户端使用此服务来终止客户端和服务器之间的数据传输&#xff08;上传或下载&#xff09;。 2.请求消息 2.1请求消息子功能参数$Level&#xff08;LEV_&#xff09;定义 此服务不使用子函数参数。 2.2请求消息数据参数定义 transferRequestParameterRecord&a…

《微服务实战》 第二十九章 分布式事务框架seata AT模式

前言 本章节介绍微服务分布式项目中&#xff0c;使用的事务框架seata。 官网&#xff1a;http://seata.io/zh-cn/ springcloud-nacos-seata&#xff1a;https://github.com/seata/seata-samples/tree/master/springcloud-nacos-seata 1、概念 Seata 是一款开源的分布式事务解…

使用docker快速搭建redis哨兵模式

说明 本文主要参考&#xff1a; https://www.cnblogs.com/coderaniu/p/15352323.html https://developer.aliyun.com/article/892805 但是这两篇博客均缺失部分关键性细节&#xff0c;所以重新撰文。读者可以结合本文和上述文章一起阅读。 安装步骤 安装docker和docker-co…

小作文--流程图(练习1)

【【雅思写作】带你打破小作文‘流程图’的传说】 https://www.bilibili.com/video/BV1QP411Q7Gh/?share_sourcecopy_web&vd_source78768d4ae65c35ff26534bbaa8afc267 雅思小作文-流程图, 看这一篇就够了! - 冯凯文的文章 - 知乎 https://zhuanlan.zhihu.com/p/35868880 …

算法模板(3):搜索(3):图论提高

图论提高 最小生成树 &#xff08;1&#xff09;朴素版prim算法&#xff08; O ( n 2 ) O(n ^ 2) O(n2)&#xff09; 适用范围&#xff1a;稠密图易错&#xff1a;注意有向图还是无向图&#xff1b;注意有没有重边和负权边。从一个集合向外一个一个扩展&#xff0c;最开始只…

记录基于Vue.js的移动端Tree树形组件

目录 一、Liquor Tree 入门 &#xff1a; Development Component Options 组件选项 Structure 结构 二、vue-treeselect Introduction 介绍 Getting Started 入门 Vue 树形选择器&#xff08; Vue tree select &#xff09;组件在搭建 Vue 的 app 中特别常用&#xff0…

【Java|golang】2611. 老鼠和奶酪

有两只老鼠和 n 块不同类型的奶酪&#xff0c;每块奶酪都只能被其中一只老鼠吃掉。 下标为 i 处的奶酪被吃掉的得分为&#xff1a; 如果第一只老鼠吃掉&#xff0c;则得分为 reward1[i] 。 如果第二只老鼠吃掉&#xff0c;则得分为 reward2[i] 。 给你一个正整数数组 reward1…

【TypeScript】枚举类型和泛型的详细介绍

目录 TypeScript枚举类型 TypeScript泛型介绍 &#x1f3b2;泛型的基本使用 &#x1f3b2;泛型接口的使用 &#x1f3b2;泛型类的使用 &#x1f3b2;泛型的类型约束 枚举类型 枚举类型是为数不多的TypeScript特有的特性之一, JavaScript是没有的&#xff1a; 枚举其实就…