Java学习之线程

线程:

1. 单线程与多线程的运行

public class DemoThread {
    public static void main(String[] args) {
        /*
            TODO 构建多线程模式
                方式1: 自定义类继承 Tread类并重写其run方法
                        在run方法中定义当前线程需要完成的任务逻辑
         */
        /*
            TODO 多线程的调用
                1.构建对象,并直接使用其run方法运行  => 单线程运行
                       对于多线程的实现,不能直接使用run方法执行
                2.构建对象,使用start方法进行运行 => 多线程运行
                        在底层会自动启动run方法,而不是在main主线程中运行run方法
         */
        // run 单线程运行
        MyThread myThread = new MyThread();
        System.out.println("run方法没有启动...");
        myThread.run();
        System.out.println("run方法启动完成...");

        // start 多线程运行
        System.out.println("run方法没有启动...");
        myThread.start(); // 启动一个新的线程用于执行当前线程对象中的run方法
        System.out.println("run方法启动完成...");
    }
}

// public class Thread 是一个具体的类 没有抽象方法
class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("这是创建的一个新线程,定义了其中的run方法...");
        }
    }
}

2. 获取线程信息

public class DemoThreadName {
    
    public static void main(String[] args) {

        /*
            TODO 获取线程名称
                ① 获取主线程的名称
                ② 自定义线程名称
         */
//        获取主线程信息
        Thread thread = Thread.currentThread(); // 获取当前正在运行的线程对象
        System.out.println("当前线程名称:" + thread.getName());
        System.out.println("当前线程ID:" + thread.getId());
        System.out.println("当前线程状态:" + thread.getState());  // RUNNABLE 表示正在运行
        System.out.println("当前线程优先权:" + thread.getPriority());


//        ThreadName threadName = new ThreadName();
//        threadName.start();  // 根据自定义类启动一个单独的线程运行run方法
//        threadName.start();  // TODO 注意:对于start方法 一个线程对象只能启动一次,否则会报错


        new ThreadName().start();  // 根据自定义类启动一个单独的线程运行run方法
        new ThreadName().start();  // TODO 每个线程对象通过start都会启动一个单独的线程,每个线程的名称都不一样

          // TODO 自定义线程名
        //利用构造器传入线程名
        new ThreadName("张三").start();
        new ThreadName("李四").start();

        ThreadName threadName = new ThreadName();
        //使用set方法传入线程名
        //public final synchronized void setName(String name)继承自父类的setName方法
        threadName.setName("王五");
        threadName.start();

    }

    static class ThreadName extends Thread {
        public ThreadName() {
        }

//        public ThreadName(String name) {
//            this.setName(name);
//        }

        //super()调用父类的构造方法
        public ThreadName(String name) {
            super(name);
        }

        @Override
        public void run() {
            while (true) {
                /*
                    public static native Thread currentThread();
                        currentThread()方法返回的是当前的Thread对象
                 */
                //写法一:Thread thread = Thread.currentThread(); thread.getName()
//                Thread thread = Thread.currentThread();
//                System.out.println("当前线程名称:" + thread.getName());
//                System.out.println("当前线程ID:" + thread.getId());
//                System.out.println("当前线程状态:" + thread.getState());
//                System.out.println("这是自定义类中的run方法执行代码...");

                //写法二:this.getName()
                System.out.println("当前线程名称:" + this.getName());
                System.out.println("当前线程ID:" + this.getId());
                System.out.println("当前线程状态:" + this.getState());
                System.out.println("当前线程优先权:" + this.getPriority());
                System.out.println("这是自定义类中的run方法执行代码...");


                // TODO 注意:当前sleep由于需要异常处理,但是run方法是重写父类方法,不能在方法中添加throws 异常信息
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

}

3. 线程优先权

public class DemoPriority {
    public static void main(String[] args) {
        /*
            TODO:
                优先权对线程执行的影响?
                ① 设置优先权
                    => 优先级设置时需要在1-10之间  => 值越大优先级越高
                      注意:对于优先级高的不一定先执行,只是获取到CPU的执行权可能性更高,执行具有一定的随机性

         */
        PriorityThread thread1 = new PriorityThread("张三");
        //设置优先权
        thread1.setPriority(1);
        PriorityThread thread2 = new PriorityThread("李四");
        thread2.setPriority(2);
        PriorityThread thread3 = new PriorityThread("王五");
        thread3.setPriority(3);

        thread2.start();
        thread1.start();
        thread3.start();
    }

    static class PriorityThread extends Thread{
        public PriorityThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("当前线程名称:" + this.getName());
                System.out.println("当前线程优先权:" + this.getPriority());
            }
        }
    }

}

4. 线程控制1

public class DemoThreadControl01 {
    
    public static void main(String[] args) throws InterruptedException {
        /*
            TODO:
                线程控制方法
                ① sleep 可以使当前的线程处于睡眠状态(具有倒计时的阻塞状态)
                    sleep(1000)  => 每次执行当前线程睡眠1秒
                    sleep(long millis, int nanos)  => 按毫秒+纳秒方式睡眠
                ② join 当使用该方法时,其他线程必须等待当前线程执行完成才能继续执行
                ③ yield 礼让线程,让当前线程退出CPU的执行权,重新竞争
                
         */

        // join
//        ControlThread thread1 = new ControlThread("李白");
//        thread1.start();
        thread1.join();
//        ControlThread thread2 = new ControlThread("张三");
//        thread2.start();

        new ControlThread("张三").start();
        new ControlThread("李四").start();
        new ControlThread("王五").start();

    }

    static class ControlThread extends Thread {
        public ControlThread(String name) {
            super(name);
        }

        // sleep睡眠
//        @Override
//        public void run() {
//            for (int i = 0; i < 10; i++) {
//                if (i % 2 == 0) {
//                    System.out.println("当前线程名称:" + this.getName() + "遇到偶数开始睡眠....");
//                    try {
//                        Thread.sleep(1000);
//                    } catch (InterruptedException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//            }
//        }


        /*
            礼让线程
         */
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                if ("张三".equals(this.getName())) {
                    System.out.println("遇到张三,开始礼让");
                    yield();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(this.getName()+"正在执行...");
                } else if ("李四".equals(this.getName())) {
                    System.out.println("遇到李四,开始礼让");
                    yield();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(this.getName()+"正在执行...");
                } else {
                    System.out.println(this.getName()+"正在执行...");
                }
            }
        }
    }

}

5. 线程控制2

public class DemoThreadControl02 {
    
    public static void main(String[] args) throws InterruptedException {
        /*
            TODO:
                线程控制方法
                ① sleep 可以使当前的线程处于睡眠状态(具有倒计时的阻塞状态)
                    sleep(1000)  => 每次执行当前线程睡眠1秒
                    sleep(long millis, int nanos)  => 按毫秒+纳秒方式睡眠
                ② join 当使用该方法时,其他线程必须等待当前线程执行完成才能继续执行
                ③ yield 礼让线程,让当前线程退出CPU的执行权,重新竞争
                ④ setDaemon 设置当前线程为后台守护线程
                       当线程设置为守护线程时,如果其他所有线程执行完成,那么当前线程也会被停止 => 放入后台执行
                ⑤ 中断线程
                        public final void stop()  强制停止  => 该方法已经过时了
                        public void interrupt() 非强制执行,在当前线程在本次CPU执行时间片断执行完成后,再进行关闭操作
                                        会有异常提示信息

         */

        //setDaemon 设置后台守护线程
//        DaemonThread thread11 = new DaemonThread("张三");
//        DaemonThread thread12 = new DaemonThread("李四");
//        thread11.setDaemon(true);
//        thread11.start();
//        thread12.start();

        StopThread thread1 = new StopThread("邱六");
        StopThread thread2 = new StopThread("王五");
        thread1.start();
        thread2.start();
 
    }

    static class DaemonThread extends Thread {
        public DaemonThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println("当前线程:" + this.getName() + "是否为守护线程:" + this.isDaemon());

                if ("张三".equals(this.getName())) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println(this.getName() + "正在执行...");
            }
        }
    }

    static class StopThread extends Thread{
        public StopThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                if ("邱六".equals(this.getName()) && i == 3){
                    //强制终止
//                    this.stop();
                    this.interrupt();//中断后会显示一个错误信息,但是并不影响程序的后续执行
                }
                System.out.println("当前线程:" + this.getName() + "当前i:" + i);
            }

        }
    }

}

6. 多线程实现两人吃西瓜

import java.util.Random;

public class DemoEatWatermelonCommentVar {
    
    public static int allNum =100;

    public static void main(String[] args) {
//        int allNum = 100; // TODO 如果将基本数据类型作为变量传入方法中,是直接将值赋予给方法中的变量;可以使用一个类来实现
        //该方法有缺陷,还未实现多个线程对同一个变量的互斥访问,后续会发解决方案
        AllWatermelon allWatermelon = new AllWatermelon();

        PeopleThread thread1 = new PeopleThread("张三", allWatermelon);
        PeopleThread thread2 = new PeopleThread("李四", allWatermelon);
        thread1.start();
        thread2.start();

    }

    static class AllWatermelon {
        private int allNum = 100;

        public void eatOne() {
            allNum -= 1;
        }

        public int getAllNum() {
            return allNum;
        }
    }


    static class PeopleThread extends Thread {
        int eatNum = 0;  // 每个线程都可以维护自身的变量
        Random random;
        AllWatermelon allWatermelon;

        public PeopleThread(String name, AllWatermelon allWatermelon) {
            super(name);
            random = new Random();
            this.allWatermelon = allWatermelon;
        }

        @Override
        public void run() {
            while (true) {
                if (allWatermelon.getAllNum() > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    eatNum += 1;
                    allWatermelon.eatOne();
                    System.out.println("当前线程:" + this.getName() + "正在吃第" + eatNum + "块西瓜," + "当前剩余的总西瓜数:" + allWatermelon.getAllNum());
                    if (eatNum % 13 == 0) {
                        System.out.println("当前线程:" + this.getName() + "吃到一颗坏瓜... 吐了...");
                    }
                }
            }
        }


    }
}

7. 通过实现 Runnable 接口来实现多线程模式

public class DemoRunnable {

    public static void main(String[] args) {
        /*
            TODO
                构建多线程模式
                 方式2: 通过实现  Runnable 接口并重写其run方法
                    该方式构建线程时,可以共用同一个Runnable接口的子实现类对象,这样就可以使用同一个对象中的变量
               好处:
                    可以避免由于Java单继承带来的局限性。
                    适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离,
                        较好的体现了面向对象的设计思想

         */
        MyRunnableThread myRunnableThread = new MyRunnableThread();
        new Thread(myRunnableThread,"线程1").start();
        new Thread(myRunnableThread,"线程2").start();
    }

    static class MyRunnableThread implements Runnable{
        int allNum = 100;
        @Override
        public void run() {
            while (true){
                if (allNum <=0){
                    break;
                }else {
                    allNum -= 1;
                    System.out.println("当前线程:"+Thread.currentThread().getName()+"allNum:"+allNum);
                }

            }
        }
    }
}

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

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

相关文章

Linux字符设备驱动(一) - 框架

字符设备是Linux三大设备之一(另外两种是块设备&#xff0c;网络设备)&#xff0c;字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备&#xff0c;常见的字符设备包括鼠标、键盘、显示器、串口等等&#xff0c;当我们执行ls -l /dev的时候&#xff0c;就能看到大量…

2024.05.06作业

自由发挥应用场景&#xff0c;实现登录界面。 要求&#xff1a;尽量每行代码都有注释。 #include "yuanshen.h"yuanshen::yuanshen(QWidget *parent): QWidget(parent) {//窗口相关设置this->resize(1600,910);this->setFixedSize(1600,910);//窗口标题this-…

管理能力学习笔记九:授权的常见误区和如何有效授权

授权的常见误区 误区一&#xff1a;随意授权 管理者在授权工作时&#xff0c;需要依据下属的能力、经验、意愿问最自己&#xff1a;这项工作适合授权给Ta做吗&#xff1f;如果没有&#xff0c;可以通过哪些方法进行培训呢&#xff1f; 误区二&#xff1a;缺乏信任 心理暗示…

腾讯崛起!2024年最赚钱的电商平台,竟然来自视频号

大家好&#xff0c;我是电商月月 说到卖货平台&#xff0c;这两年“抖音”绝对是所有人心里最赚钱的电商平台 抖音小店的商家利用抖店后台的“精选联盟”引流&#xff0c;不用自己直播&#xff0c;也能靠直播卖货赚的盆满钵满 于是好多平台都效仿抖店的直播卖货形式来获取更…

BGP的选路 :

前提条件 &#xff1a; 丢弃所有不可用的路由信息。 属性的名称 传播范围 默认值 评判标准 PV&#xff08;优选值&#xff09; 不传播 0&#xff08;0-65535&#xff09; 越大越优 LP&#xff08;本地优先级&#xff09; IBGP对等体 之间 100 越大越优 AS_PATH …

中间件研发之Springboot自定义starter

Spring Boot Starter是一种简化Spring Boot应用开发的机制&#xff0c;它可以通过引入一些预定义的依赖和配置&#xff0c;让我们快速地集成某些功能模块&#xff0c;而无需繁琐地编写代码和配置文件。Spring Boot官方提供了很多常用的Starter&#xff0c;例如spring-boot-star…

PMO全面指南:一文读懂PMO的功能、职责、类型、构建

多年来&#xff0c;PMO 的概念在多个行业和类型的组织中越来越受欢迎。一开始&#xff0c;只有大型跨国公司才熟悉它&#xff0c;但后来&#xff0c;许多中小型公司开始采用 PMO 来进行高效的项目管理并实现其战略目标。 根据Statista的数据&#xff0c;目前有80%的组织设有至…

企业网站 | 被攻击时该怎么办?

前言 每天&#xff0c;数以千计的网站被黑客入侵。发生这种情况时&#xff0c;被入侵网站可用于从网络钓鱼页面到SEO垃圾邮件或者其它内容。如果您拥有一个小型网站&#xff0c;很容易相信黑客不会对它感兴趣。不幸的是&#xff0c;通常情况并非如此。 黑客入侵网站的动机与所…

09_电子设计教程基础篇(电阻)

文章目录 前言一、电阻原理二、电阻种类1.固定电阻1、材料工艺1、线绕电阻2、非线绕电阻1、实心电阻1、有机实心电阻2、无机实心电阻 2、薄膜电阻&#xff08;常用&#xff09;1、碳膜电阻2、合成碳膜电阻3、金属膜电阻4、金属氧化膜电阻5、玻璃釉膜电阻 3、厚膜电阻&#xff0…

segformer部分错误

亲测有用 1、TypeError: FormatCode() got an unexpected keyword argument ‘verify‘ mmcv中出现TypeError: FormatCode() got an unexpected keyword argument ‘verify‘-CSDN博客 pip install yapf0.40.0 2、“EncoderDecoder: ‘mit_b1 is not in the backbone regist…

达梦数据库导入数据问题

进行数据导入的时候遇到了导入数据问题 第一个问题&#xff1a; 该工具不能解析此文件&#xff0c;请使用更高版本的工具 这个是因为版本有点低&#xff0c;需要下载最新的达梦数据库 第二个问题&#xff1a; &#xff08;1&#xff09;本地编码&#xff1a;PG_GBK, 导入文…

美特CRM upload.jsp 文件上传致RCE漏洞复现(CNVD-2023-06971)

0x01 产品简介 MetaCRM是一款智能平台化CRM软件,通过提升企业管理和协同办公,全面提高企业管理水平和运营效率,帮助企业实现卓越管理。美特软件开创性地在CRM领域中引入用户级产品平台MetaCRM V5/V6,多年来一直在持续地为客户创造价值,大幅提升了用户需求满足度与使用的满意…

21 内核开发-临界区及临界区代码段判断

内核开发-临界区判断 目录 内核开发-临界区判断 1.定义 2.临界区实现机制 3.使用互斥锁实现临界区的示例 4.怎么识别是临界区代码 5.总结 1.定义 临界区是计算机系统中的一段代码&#xff0c;在任何时刻只能被一个线程执行。临界区的目的是防止多个线程同时访问共享资源…

Make3D数据集相关介绍

一、参考资料 Make3d数据集使用方法 二、相关介绍 1. 简介 Make3D 数据集的每帧图像的深度值均由激光雷达进行采集&#xff0c;相较于 Kinect 相机采集的深度信息&#xff0c;该测距仪可以得到室外图像更加精确的深度信息&#xff0c;而且测距范围更大&#xff0c;与普通的…

【stm32笔记】DSP库调用

参考&#xff1a;DSP库调用 , __CC_ARM,__TARGET_FPU_VFP, __FPU_PRESENT1U, ARM_MATH_CM4把需要的库复制出来单独用&#xff0c;方便移植

websevere服务器从零搭建到上线(三)|IO多路复用小总结和服务器的基础框架

文章目录 epollselect和poll的优缺点epoll的原理以及优势epoll 好的网络服务器设计Reactor模型图解Reactor muduo库的Multiple Reactors模型 epoll select和poll的优缺点 1、单个进程能够监视的文件描述符的数量存在最大限制&#xff0c;通常是1024&#xff0c;当然可以更改数…

什么是X电容和Y电容?

先补充个知识&#xff1a; 一、什么是差模信号和共模信号 差模信号&#xff1a;大小相等&#xff0c;方向相反的交流信号&#xff1b;双端输入时&#xff0c;两个信号的相位相差180度 共模信号&#xff1a;大小相等。方向相同。双端输入时&#xff0c;两个信号相同。 二、安规…

小程序如何重启

用户在使用小程序的过程中&#xff0c;有时候会碰到一些问题。比如小程序数据不加载、卡顿、崩溃或者出现其他异常情况。这时候&#xff0c;最简单的办法就是重启小程序。但是很多客户不知道如何重启小程序&#xff0c;下面就具体介绍小程序重新启动的几种方法。 1. 强制关闭&…

CWDM、DWDM、MWDM、LWDM:快速了解光波复用技术

在现代光纤通信领域&#xff0c;波分复用&#xff08;WDM&#xff09;技术作为一项先进的创新脱颖而出。它通过将多个不同波长和速率的光信号汇聚到一根光纤中来有效地传输数据。本文将深入探讨几种关键的 WDM 技术&#xff08;CWDM、DWDM、MWDM 和 LWDM&#xff09;&#xff0…

流量分析。

流量分析 在Wireshak抓包可以看到正常的执行流程如下&#xff1a; ● Client向Server发起Load data local infile请求 ● Server返回需要读取的文件路径 ● Client读取文件内容并发送给Server ● PS&#xff1a;在本机上启动服务端与客户端&#xff0c;启动wireshark 抓包&…