Java进行多线程编程?(lambda表达式~)

news2024/11/16 22:00:57

本文标题:Java进行多线程编程?那么,Java为啥不学学如何进程多进程编程呢??原因在于:Java圈子中不提倡多进程编程~~

接下来,我们来写一个最为基础/入门的HelloWord程序来感受如何进行多线程~~
Java标准库提供了一个类Thread能够表示一个线程~

public class MyThread extends Thread {
    //继承:创建一个类MyThread,继承标准库的Thread
    @Override
    public void run(){//重写,子类重写父类的方法
        System.out.println("Hello Word");
    }

    public static void main(String[] args) {
        //先创建MyThread实列,t的引用实际上是指向子类的实列
        Thread t=new MyThread();
        //启动线程,再进程中搞了另外一个流水线,新的流水线开始并发的执行另外一个逻辑了~
        t.start();
    }
}

在上述的代码段中,主要涉及到两个线程:

  1. main方法所对应的线程(一个进程中至少得有一个线程),也可也称为主线程;
  2. 通过t.start()创建的新的线程

通过右键运行main方法,其实是idea对应的进程,创建了一个新的Java进程,这个Java进程来执行咱们自己写的代码,这个Java进程里就有两个线程,一个是main线程,另一个是t线程~

调整代码,具体仔细看一下,体会一下:“每个线程都是一个独立的执行流~”;

public class MyThread extends Thread {
    //继承:创建一个类MyThread,继承标准库的Thread
    @Override
    public void run(){//重写,子类重写父类的方法
//        System.out.println("Hello Word");
        
        //死循环
        while (true){
            System.out.println("hello  t ---->t线程");
        }
    }

    public static void main(String[] args) {
        //先创建MyThread实列,t的引用实际上是指向子类的实列
        Thread t=new MyThread();
        //启动线程,再进程中搞了另外一个流水线,新的流水线开始并发的执行另外一个逻辑了~
        t.start();
        
        //死循环
        while (true){
            System.out.println("hello  main  ---->main线程");
        }
    }
}

在上述的代码中,t线程和main线程都写了一个while(true)的死循环,按道理来说,一进入while(true)就会死循环了,但是,实际的代码运行情况却不是这样的~~

截取自运行结果部分示意图~

观看运行结果,显而易见的可以得到:交替打印~,此时看到的效果:hello  t ---->t线程和hello  main  ---->main线程都能打印出来,通过t.start()另外启动了一个执行流,而新的执行流(新的线程)来执行        while (true){System.out.println("hello  t ---->t线程"); },因此这段代码与        while (true){System.out.println("hello  main  ---->main线程"); }看起来在同时执行;

线程是能够交替运行的,但是打印出来的结果肯定是有先后的!!因为两个线程往同样一个控制台上控制,同一个控制台必须得顺序输出~!

通过上述代码的运行结果,我们可以看到这两个线程就算再同时执行,先打印几个hello  t ---->t线程,再打印几个hello  main  ---->main线程…………,如果是单个线程的话,此时就是只能打印其中一个,看不到另外一个!

当然,我们对上述代码的main方法做出简单更改!


public class MyThread extends Thread {
    //继承:创建一个类MyThread,继承标准库的Thread
    @Override
    public void run(){//重写,子类重写父类的方法
//        System.out.println("Hello Word");

        //死循环
        while (true){
            System.out.println("hello  t ---->t线程");
        }
    }

    public static void main(String[] args) {
        //先创建MyThread实列,t的引用实际上是指向子类的实列
        Thread t=new MyThread();
        //启动线程,再进程中搞了另外一个流水线,新的流水线开始并发的执行另外一个逻辑了~
        //start()会创建新的线程
        //t.start();
        //run不好创建新的线程,run是在main线程中执行的
        t.run();

        //死循环
        while (true){
            System.out.println("hello  main  ---->main线程");
        }
    }
}

代码的运行结果为:

此处,代码没有创建其他的线程,两个死循环都在同一个线程中,执行到第一个死循环后,代码就出不来了,第二个死循环就进不去了,因此,代码会一直在打印:hello  t ---->t线程

在MyThread中:

public class MyThread extends Thread {
    //继承:创建一个类MyThread,继承标准库的Thread
    @Override
    public void run(){//重写,子类重写父类的方法
//        System.out.println("Hello Word");

        //死循环
        while (true){
            System.out.println("hello  t ---->t线程");
        }
    }
}

run()方法:线程的入口方法;

run()方法不是一个随便的方法,是重写了父类的方法~

这种重写一般就是:功能的扩展

一般这样的重写方法是不需要咱们自己手动调用的,已经有其他代码来调用了~如果我们随便写了run2()方法,这样的方法没有在t.start()中被调用,是无法自动执行的~

t.start()方法:调用操作系统的API,创建新的线程,从而新的线程里调用t.run()方法

上述的代码打印太快,不利于查看,可以加thread.sleep(1000),1000是指1000毫秒等于1秒

sleep是Thread的静态方法(通过类名调用)。(报错的话,抛出异常即可)

当然,sleep(1000)仅之休眠一秒,之后的打印结果也不是严格意义上的交替,每一秒过后,是先打印main线程,还是先打印t线程,都是不确定的,因为多个线程在CPU上调度执行的顺序是不确定的(随机);

线程虽然有优先级,但是,这个优先级对于系统来说,只是“建议”

program---->jdk---->bin---->jconsloe.exe应用程序,使用这个jdk提供的工具,就能够给我们查看出Java进程里的线程详情~~

jconsloe只能分析Java进程,不能识别非Java进程,主注意:idea是用Java写的,jconsloe也是用Java写的(占用两个进程,需要注意区分-----》看名字)

当然,有的同学运行jconsloe发现进程列表是空的,大概率是权限问题,右键----》以管理员方式运行即可~(确保代码在运行中,才能看到~)

上述的代码是:使用继承Thread,重写run()方法的方式来创建线程(使用Thread的run()描述线程的入口)

接下来,我们使用实现Runnable,通过重写run方法的方式来创建线程(使用Runnable的interface来描述线程的入口~)

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        while (true){
            System.out.println("hello t---->t线程");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyRunnable runnable=new MyRunnable();
        Thread t=new Thread(runnable);
        t.start();

        while (true){
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

对于上述代码的运行结果,大家可自行尝试(交替打印)

3.继承Thread,使用匿名内部类(内部类:定义在类里面的类)

public class Main1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(){
            @Override
            public void run(){
                while (true){
                    System.out.println("hello t---->t线程");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        
        t.start();
        while (true){
            System.out.println("hello main---->main线程");
            Thread.sleep(1000);
        }
    }
}

4.实现Runnable使用匿名内部类

public class Main1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(){
            @Override
            public void run(){
                while (true){
                    System.out.println("hello t---->t线程");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        
        t.start();
        while (true){
            System.out.println("hello main---->main线程");
            Thread.sleep(1000);
        }
    }
}

需要注意的是:{ }放到哪里,就算针对哪个类创建的匿名内部类

当然,创建线程最推荐的写法:使用lambda表达式!!最简单最直观的写法(前面几种可以不记)

lambda表达式:本质就是一个匿名函数!!(没有名字的函数,这种一般是一次性的),Java里面函数(方法)是无法脱离类的,在Java里面lambda就相当于一个列外!!

lambda表达式的基本写法:()->{ }

()小括号里面放参数,如果只有一个参数()可省略

{ }大括号里面放函数,写各种Java代码,如果只有一行代码,{ }可省略

那么,我们来看一下具体的写法吧~

public class ThreadDemos {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            while (true){
                System.out.println("hello t---->t线程");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        
        t.start();
        while (true){
            System.out.println("hello main---->main线程");
            Thread.sleep(1000);
        }
    }
}

上述的代码即为lambda表达式的写法(强调~)

更多关于lambda表达式的资料,请详见:百度安全验证

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

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

相关文章

数据资产管理:数据目录怎么搞?

经过了站在业务视角的自上而下的数据梳理,以及站在IT视角的自下而上的数据盘点,一套“热腾腾”的数据资产清单终于新鲜出炉了。 通过数据资产盘点,企业终于知道他们拥有哪些数据、如何使用数据、是否安全以及数据在哪里。 然而,据…

数据库误修改后的数据恢复

一不小心将数据库数据修改了,而且回滚无效,于是去尝试各种方法恢复数据 查询到修改时间点之前的数据 恢复数据 恢复数据库被修改数据的流程及代码,这里被修改的表是AUTH_USER,实际应用填写对应表名。 -- 通过时间恢复删除且已提交的数据-- 1…

Jenkins安装配置及插件安装使用

个人理解持续集成:为解决程序代码提交质量低,提交内容导致原有系统的BUG,按时或按需自动编译版本,进行自动化测试。 百度对持续集成的定义:持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,…

配额 安排

一 常用Tcode 基于Tcode的顺序排列 供应商主数据物料主数据货源清单配额安排采购信息记录采购订单框架协议采购询价/报价采购申请订单收货发票校验物料需求计划BP-供应商主数据MM01 - 物料主数据新增ME01 - 维护MEQ1 - 维护ME11 - 创建ME21N - 创建框架协议-合同&#xff1a…

Qt6_贪吃蛇Greedy Snake

贪吃蛇Greedy Snake 1分析 首先这是一个贪吃蛇界面,由一个长方形边框和一只贪吃蛇组成 默认开局时,贪吃蛇身体只有3个小方块,使用画笔画出 1.1如何移动 对于蛇的移动,有2种方法 在一定时间范围内(定时器),未对游戏…

谷歌 reCAPTCHA 人机验证

一、问题 smogon 论坛注册不成功。输入账号、密码、邮箱后显示 You did not complete the CAPTCHA verification properly. Please try again. 即未通过 CAPTCHA 验证。 二、原因 使用的 CAPTCHA 验证是谷歌的 reCAPTCHA 人机验证,国内无法访问谷歌服务。 三、解决…

分页查询实现

目录 1.实体类 2.Mapper层 2.1.xxxMapper接口 2.2.xxxMapper.xml文件 3.Service层 3.1.xxxService接口 3.2.xxxServiceImpl层 4.xxxController层 5.调用接口 6.总结 1.实体类 与数据库交互和与前端交互的实体类 这个Model是与数据库交互的实体类,其中的…

python调用GPT实现:智能用例生成工具

工具作用: 根据输入的功能点,生成通用测试点 实现步骤 工具实现主要分2个步骤: 1.https请求调用Gpt,将返回响应结果保存为.md文件 2.用python实现 将 .md文件转换成.xmind文件 3.写个简单的前端页面,调用上述步骤接口 详细代…

7个数据科学Python库将为您节省大量时间

7个数据科学Python库将为您节省大量时间 在进行数据科学时,您可能会花费大量时间编写代码并等待计算机运行某些操作。我挑选了一些可以在这两种情况下节省您时间的Python库。即使您只将其中一个库纳入您的工具库,您仍然可以在下次项目工作时节省宝贵的时…

揭示OLED透明屏数据:探索未来显示技术的潜力

OLED透明屏作为一项颇具吸引力的显示技术,以其独特的特点和卓越的画质在市场上引起了广泛关注。 在这篇文章中,尼伽将和大家一起深入探索OLED透明屏的数据,通过具体的市场趋势分析、技术指标解析、应用领域探讨和未来前景展望,为…

【C++基础】实现日期类

​👻内容专栏: C/C编程 🐨本文概括: C实现日期类。 🐼本文作者: 阿四啊 🐸发布时间:2023.9.7 对于类的成员函数的声明和定义,我们在类和对象上讲到过,需要进行…

mac 查看端口占用

sudo lsof -i tcp:port # 示例 sudo lsof -i tcp:8080 杀死进程 sudo kill -9 PID # 示例 sudo kill -9 8080

“搞事情”?OpenAl将于11月召开其首届开发者大会

摘要:OpenAI也要召开它的第一届开发者大会了。这次活动,或许标志着OpenAI向其下一阶段的商业开发迈出了关键一步。 昨天,OpenAI宣布将于11月6日举办其首次开发者大会。在这场名为“OpenAI DevDay”的活动中,OpenAI的技术人员将进行…

欧科云链与HashKey Exchange达成合作,助力香港虚拟资产合规化

继8月10日 欧科云链 与 华为云 达成合作之后, 今天,欧科云链 又与 Hashkey Exchange 共同宣布正式达成合作! 这次与Hashkey达成合作,双方又将在Web3行业中谱写怎样的故事? 9月6日,欧科云链控股有限公司&…

2023 年高教社杯全国大学生数学建模竞赛题目 C 题 蔬菜类商品的自动定价与补货决策

C 题 蔬菜类商品的自动定价与补货决策 在生鲜商超中,一般蔬菜类商品的保鲜期都比较短,且品相随销售时间的增加而变差, 大部分品种如当日未售出,隔日就无法再售。因此,商超通常会根据各商品的历史销售和需求情况每天进…

生物通路数据库收录1600+整合的经典通路

生物通路数据库为科学家提供了关于生物通路的大量信息和资源,特别是在数据整合、信息检索、数据可视化分析、数据交互、生物学研究等方面,积极推动了生物学研究和科学的发展。 世界各地正在创建各种类型的通路数据库,每个数据库都反映了其创…

快递批量查询高手必备的实用工具

在网购日益普及的今天,我们经常需要查询快递的物流信息。但是,传统的查询方式一个一个地输入快递单号,不仅费时费力,还容易出错。有没有一种方法可以批量查询多个快递单号呢?答案是肯定的,今天我们就来介绍…

2140. 解决智力问题;1401. 圆和矩形是否有重叠;901. 股票价格跨度

2140. 解决智力问题 核心思想:动态规划。dp[i]表示解决i-n-1的问题所能获得的最高分数,注意需要倒叙遍历,因为i的状态由后面的状态转移过来的。 1401. 圆和矩形是否有重叠 核心思想:分情况讨论,圆心情况。借用别人一张图说明。 …

JWT-Token升级方案

1. 介绍 JWT是JSON Web Token的缩写,即JSON Web令牌,是一种自包含令牌。 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资…