Java多线程2 线程创建的两种方式与Thread类常用方法

Java多线程--创建多线程的基本方式一:继承Thread类 阅读详情

/*
线程的创建方式

一 Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread类来体现。
Thread类的特性
1,每个线程都是通过某个特定Thread对象的run()方法来完成操作的,经常
把run()方法的主体称为线程体
2,通过该Thread对象的start()方法来启动这个线程,而非直接调用run()
3,构造器
*Thread():创建新的Thread对象
*Thread(String threadname):创建线程并指定线程实例名
*Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接口中的run方法
*Thread(Runnable target, String name):创建新的Thread对象
4,常用方法
*void start(): 启动线程,并执行对象的run()方法
*void run(): 线程在被调度时执行的操作
*String getName(): 返回线程的名称
*void setName(String name):设置该线程名称,也可以通过构造器命名
*static Thread currentThread(): 返回当前线程。在Thread子类中就是this,通常用于主线程和Runnable实现类
*static void yield():线程让步,主动释放当前线程的cpu资源,但下一步cpu如何分配无法确定。
1暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程
2若队列中没有同优先级的线程,忽略此方法
*join() :当某个程序执行流中调用其他线程的 join() 方法时,调用线程将
被阻塞,直到 join() 方法加入的 join 线程执行完为止,低优先级的线程也可以获得执行
*static void sleep(long millis):(指定时间:毫秒)
1令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。
2抛出InterruptedException异常
*stop(): 强制线程生命期结束,不推荐使用
*boolean isAlive():返回boolean,判断线程是否还活着
使用注意:

  1. 如果自己手动调用run()方法,那么就只是普通方法,没有启动多线程模式。
  2. run()方法由JVM调用,什么时候调用,执行的过程控制都有操作系统的CPU调度决定。
  3. 想要启动多线程,必须调用start方法。
  4. 一个线程对象只能调用一次start()方法启动,如果重复调用了,则将抛出以上的异常“IllegalThreadStateException”。
    5,yield()方法下一步执行哪个线程看概率,sleep()方法会使线程在之后确定的时间段内被阻塞,之后重新排队
    join()方法会使当前线程被阻塞到插入的线程执行完毕后才会被执行。
    6.join()方法与sleep()方法都需要处理异常。
    7,Thread的匿名子类无法调用join方法,因为需要先调用一次start()方法启动线程才能加入其他线程中。

二 Java中线程的调度方法
1同优先级线程组成先进先出队列(先到先服务),使用时间片策略
2对高优先级,使用优先调度的抢占式策略

线程的优先级等级
thread类中的常量,可以直接调用
MAX_PRIORITY:10 最大
MIN _PRIORITY:1 最小
NORM_PRIORITY:5 默认

涉及的方法
getPriority() :返回线程优先值
setPriority(int newPriority) :改变线程的优先级,范围1-10

说明
线程创建时继承父线程的优先级,未设置情况下默认优先级是5.
低优先级只是获得调度的概率低,并非一定是在高优先级线程之后才被调用

三创建线程的方式
JDK1.5之前创建新执行线程有两种方法:
*继承Thread类的方式
*实现Runnable接口的方式

方式一:继承Thread类
1 定义子类继承Thread类。
2 子类中重写Thread类中的run方法。
3 创建Thread子类对象,即创建了线程对象。
4 调用线程对象start方法:启动线程,调用run方法。

方式二:实现Runnable接口
1 定义子类,实现Runnable接口。
2 子类中重写Runnable接口中的run方法。
3 通过Thread类含参构造器创建线程对象。
4 将Runnable接口的子类对象作为实际参数传递给Thread类的构造器中。
5 调用Thread类的start方法:开启线程,Thread类中的run()方法调用的是Runnable接口实现类的run方法。

继承方式和实现方式的联系与区别
区别
*继承Thread:线程代码存放Thread子类run方法中。
*实现Runnable:线程代码存在接口的子类的run方法。
实现方式的好处
*避免了单继承的局限性
*多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。

*/

package leanthread;

import com.sun.jmx.snmp.SnmpUnknownAccContrModelException;

import javax.xml.namespace.QName;

/**
 * @Description:
 * @Version:1.0.0.1
 * @Date:2020--03--03--22:07
 * @Author:wisdomcodeinside
 * @E-mail:liwenfeixiaoyao@163.com
 */
public class ThreadTest2 {
    public static void main(String[] args) {
        OddThread o = new OddThread();//主线程创建对象
        o.start();//start()方法开始创建分支线程,然后调用当前线程的run()方法,方法体是重写的方法体
//      o.run();//此时只是在主线程中执行对象的run()方法,不是在分支线程中运行。
//      o.start();//会报IllegalThreadStateException异常,同一个线程子类的对象不能启动两次。
        OddThread o1 = new OddThread("无名");
        o1.start();//新对象可以启动新线程
        Thread.currentThread().setName("老大哥");//可以对主线程命名
        Thread.currentThread().setPriority(10);//可以设置主线程优先级
        //主线程输出方法
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + "主线任务"
                    + "任务等级" + Thread.currentThread().getPriority() + "完成次数" + i);//主线程与分支线程的输出会交错显示。
            if (i == 49) {
                try {
//                    new Thread(){
//                        @Override
//                        public void run() {
//                            for (int j = 0; j < 10; j++) {
//                                System.out.println("奇遇任务" + j);
//                            }
//                        }
//                    }//匿名子类无法start()
                    o1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        //对于只使用一次的线程可以使用匿名子类的方式
        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + "\t无心");
                    if (i % 2 == 0) {
                        this.yield();
                        try {
                            sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + "\t法师");
                    try {
                        sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        //倒计时
        new Thread() {
            @Override
            public void run() {
                System.out.println("您的GTX690即将启动");
                for (int i =10; i > 0; i--) {
                    System.out.println(i);
                    try {
                        sleep(1000);//1000毫秒为1秒
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("Fallout");
            }
        }.start();
        //查看线程状态
        System.out.println(o.isAlive());
        System.out.println(o1.isAlive());
        System.out.println(Thread.currentThread().isAlive());
        //测试买票线程
        SellTicketWindow window1 = new SellTicketWindow("窗口1");
        SellTicketWindow window2 = new SellTicketWindow("窗口2");
        SellTicketWindow window3 = new SellTicketWindow("窗口3");
        window1.start();
        window2.start();
        window3.start();
        //测试买票线程
        TicketWindow t = new TicketWindow();
        Thread ticketWindow1 = new Thread(t);
        Thread ticketWindow2 = new Thread(t);
        Thread ticketWindow3 = new Thread(t);
        ticketWindow1.setName("卖票窗口1");
        ticketWindow1.start();
        ticketWindow2.setName("卖票窗口2");
        ticketWindow2.start();
        ticketWindow3.setName("卖票窗口3");
        ticketWindow3.start();
    }
}

class OddThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i % 2 != 0) {
                System.out.println(Thread.currentThread().getName() + "支线任务"
                        + "任务等级" + Thread.currentThread().getPriority() + "完成次数" + i);//获取当前线程的名字
            }
        }
    }

    public OddThread(String name) {
        super(name);
    }

    public OddThread() {
        super();
    }
}
//继承Thread类来创建线程
class SellTicketWindow extends Thread{
    private static int ticket = 100;//ticket是线程共用的属性,必须声明为static的,或者类继承Runnable接口
    private int total = 0;
    @Override
    public void run() {
        while (true) {
            if(ticket > 0){
                System.out.println(getName() + "卖出一张票," + "票号为:" + ticket);
                ticket--;
                total++;
            }else{
                System.out.println("票已卖完,谢谢关照");
                System.out.println(Thread.currentThread().getName() + "总共卖出" + total + "张票");
                break;
            }
        }
    }
    public SellTicketWindow(String name){
        super(name);
    }
}
//实现Runnable接口来创建线程
class TicketWindow implements Runnable {
    private int ticket = 100;//线程共用一个对象,不用加上static
    @Override
    public void run() {
        while (true) {
            if(ticket > 0){
                System.out.println(Thread.currentThread().getName() + "卖出一张票," + "票号为:" + ticket);
                ticket--;
            }else{
                System.out.println("票已卖完,谢谢关照");
                break;
            }
        }
    }
}
图像去噪实战:Noise2Noise与Noise2Void在医学影像中的应用(附代码) 本文深入探讨了Noise2Noise与Noise2Void在医学影像去噪中的革命性应用,通过自监督学习技术有效解决临床数据配对难题。文章提供详细的代码实现和临床部署方案,展示如何提升低剂量CT、MRI等影像的诊断质量,特别适用于辐射敏感场景和急诊快速处理。 阅读详情

相关推荐

别再死记硬背了!用LTspice和Simulink仿真,5分钟搞懂巴特沃斯、切比雪夫、贝塞尔滤波器的区别

本文通过LTspice和Simulink仿真工具,直观对比了巴特沃斯、切比雪夫和贝塞尔滤波器的特性差异。从通带波纹、过渡带陡峭度到相位线性度,详细解析了三种经典滤波器的设计哲学与应用场景,帮助工程师和学生快速掌握滤波器选型技巧,提升电路设计效率。

weixin_33910191的博客 523

创建线程的两种方式

先来了解一下与线程相关的概念,如程序,进程,以及他们之间的区别 1)、程序Program: 程序是一段静态的代码, 它是应用程序执行的蓝本。 2)、进程Process 进程是指一种正在运行的程序, 有自己的地址空间。 3)、线程Thread 进程内部的一个执行单元, 它是程序中一个单一的顺序控制流程。线程又被称为轻量级进程(lightweight process)。如果在一个进程中同时运行了多个线...

莫失莫忘的博客 2046

【正点原子STM32连载】第六十章 串口IAP实战:从Bootloader到APP的无缝升级

本文以正点原子STM32F103开发板为例,详细讲解了串口IAP(在应用编程)技术的实现原理与实战步骤。内容涵盖Bootloader与APP的分工、FLASH空间规划、核心代码解析以及Ymodem协议的应用,旨在帮助开发者掌握通过串口为嵌入式设备实现远程固件升级的关键技术,提升产品维护与迭代效率。

weixin_29161719的博客 444

创建线程的几种方式

创建线程的几种方式

inexaustible的博客 3199

你的App合规吗?手把手教你用Camille生成隐私调用报告给老板看

本文详细介绍了如何使用开源工具Camille进行Android App隐私合规检测,并生成高管易懂的隐私调用报告。通过动态插桩技术和多维度分析,Camille能有效识别高风险API调用,并将其映射到具体法律条款,帮助技术团队与法务、产品等非技术部门高效沟通,确保App符合《个保法》等法规要求。

weixin_33726318的博客 422

OpenCV+ArUco实战:如何用Python实现高精度二维码测距(附完整代码)

本文详细介绍了如何使用Python和OpenCV实现基于ArUco标签的高精度单目视觉测距。通过相机标定、标签检测和三维位置估算,结合完整代码示例,帮助开发者在机器人导航、工业自动化等场景中实现厘米级距离测量,并探讨了精度优化与三维可视化等进阶应用。

weixin_29052717的博客 474

线程的4种创建方式

多线程创建的4种方式

激流丶的博客 3764

各种逻辑漏洞

注册:短信轰炸验证码安全问题密码爆破邮箱轰炸用户任意注册、批量注册用户名枚举XSS(有框的地方就可以尝试插XSS)登录:短信轰炸、验证码安全问题、密码爆破、邮箱轰炸SQL注入撞库抓包把password字段修改为空值发送认证凭证替换、比如返回的数据包中包含账号,修改账号就能登录到其他账号Cookie仿冒修改返回包的相关数据,可能会登陆到其他的用户找回密码:短信邮箱轰炸、短信邮箱劫持重置任意用户账户密码、验证码手机用户未统一验证直接跳过验证步骤。

shirlly_的博客 2091

创建线程的四种方式

无

m0_58473539的博客 5649

GraphRAG 与 HippoRAG 深度对比:在 RAGFlow 中如何选择知识图谱方案?

本文深入对比了GraphRAG与HippoRAG在RAGFlow中的知识图谱构建方案,分析了两者在技术架构、资源消耗和场景适配性上的核心差异。GraphRAG适合需要快速响应和资源有限的场景,而HippoRAG则更适用于精确关系推理的专业领域。文章还提供了RAGFlow的演进路线和选型决策框架,帮助架构师根据实际需求做出合理选择。

weixin_27889245的博客 246

FFMPEG音频开发: Linux下采集摄像头(使用V4L2框架)数据录制成MP4视频保存到本地

一、环境介绍 操作系统介绍:ubuntu 18.04 FFMPEG版本: 4.4.2 摄像头: USB摄像头、虚拟机挂载本机自带摄像头 二、FFMPEG与X264下载编译 X264下载地址: http://www.videolan.org/developers/x264.html FFMPEG下载地址:https://ffmpeg.org/download.html Yasm ...

8868

Java多线程之线程的创建与Thread类的使用

本篇文章介绍java多线程中Thread类的使用以及有关线程对象创建和常用方法。

未见花闻的博客 3169

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Java多线程:常见的线程的创建方法及Thread类详解

线程是程序的执行流程的最小单元,一个进程(程序的执行实例)可以由一个或多个线程组成,每个线程都有自己的执行路径和执行状态。线程可以并发执行,即多个线程可以同时在不同的处理器核心或计算机上运行,从而提高程序的运行效率。线程与进程的区别在于,进程是操作系统对一个正在运行的程序的抽象,而线程是进程内部的一个执行单位。一个进程可以有多个线程,这些线程共享进程的资源,如内存空间、文件描述符等。线程之间可以通过共享内存的方式进行通信,相比于进程间通信(如管道、消息队列)的开销更小。

luming的博客 1651

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

22、java 多线程之一:继承 Thread 类创建多线程(方式一)、实现 Runnable 接口创建多线程(方式二)、两种方式创建多线程利弊及问题

/ 设置线程的优先级操作、获取当前代码的线程操作、获取和设置当前线程的名称操作、释放线程当。内的偶数,一个进程遍历。// 发现:确实是启动了。// 发现:确实是启动了。// 发现:确实是启动了。内的偶数,且可以获取和。// 发现:确实是启动了。问题,后面会被解决;问题,后面会被解决;

狮子座的男孩 1489

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java创建多线程的两种方式:继承Thread类和实现Runnable接口

继承Thread类:继承Thread类,再重写Thread类的Run方法,然后调用start()方法启动线程,启动线程后执行的是run方法。注意:多次启动线程(多次调用start()方法)是不合法的。 实现Runnable接口:实现Runnable接口,再重写run方法,然后将这个实现类当做参数传给Thread类,例如:Thread dog = new Thread(runn,"小狗"),创建...

学习笔记 1万+

Java多线程的创建与Thread类的方法及使用

一个线程就是一个 “执行流”. 每个线程之间都可以按照顺讯执行自己的代码. 多个线程之间 “同时” 执行着多份代码.举个例子如下场景:一家公司要去银行办理业务,既要进行财务转账,又要进行福利发放,还得进行缴社保。如果只有张三一个会计就会忙不过来,耗费的时间特别长。为了让业务更快的办理好,张三又找来两位同事李四、王五一起来帮助他,三个人分别负责一个事情,分别申请一个号码进行排队,自此就有了三个执行流共同完成任务,但本质上他们都是为了办理一家公司的业务。

积跬步以至千里 1009

创建线程的两种方式:继承Thread类和实现Runnable接口

第一种方式:继承Thread类 步骤:1、定义类继承Thread 2、覆写Thread类的run方法。 自定义代码放在run方法中,让线程运行 3、调用线程的star方法, 该线程有两个作用:启动线程,调用run方法。 代码示例: class Test extends Thread { //private String name; Te...

一只苟延残喘的卑微蝼蚁 5326

java 多线程之继承Thread类实现创建多线程及实现Runnable接口创建多线程

java 多线程之继承Thread类实现创建多线程1.Java 多线程之Thread类2.继承Thread类实现创建多线程3.Thread类常用的方法 1.Java 多线程之Thread类 Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread类来实现。 Thread类的特性 ① 每个线程都是通过某个特定Thread对象的run()方法来完成操作的,经常把run(...

码农回顾 2540

【Java多线程(1)】创建线程的几种方式和Thread类及其常见方法

在 Java 中的线程(Thread)是由 Java 虚拟机(JVM)来管理和调度的,它们并不直接映射到操作系统的原生线程(OS Thread)。Java 线程是由 JVM 在后台使用一种称为“轻量级进程(Lightweight Process)”的概念来实现的。

StuLearn-LJC的博客 1204

JAVA-Thread类实现多线程

如果某个线程在执行过程中,能够阻止进程结束,此时这个线程就是“前台线程”,只要当进程中的所有前台线程都结束那么这个进程才可以结束。try {});t1.start();// 是否为后台线程如果这个线程执行过程中,不能阻止进程结束(虽然线程在执行着,但是进程要结束了,此时这个线程也会随之被带走),这样的线程就是“后台线程”。try {});//设置线程为后台线程,需要在start之前设置t1.start();

Lizhihao_的博客 1283

【Java】多线程(篇一) : 通过Thread类创建线程的方法

【Java】多线程:通过Thread类创建线程的方法 1. 创建一个类, 继承Thread, 重写run方法 用线程来写一个简单的 hello word: 多线程的无限循环 以及调试器 调试器 2. 创建一个类, 实现Runnable , 重写 run 方法

mmmocen的博客 1248

Java>多线程>>创建多线程程序的两种方法(创建Thread类的子类、实现Runnable接口)

创建多线程程序的第一种方式:创建Thread类的子类 。 java.lang.Thread类:是描述线程的类,我们想要实现多线程程序,就必须继承Thread类。 实现步骤: 创建一个Thread类的子类。 在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么?)。 创建Thread类的子类对象 调用Thread类中的方法start方法,开启新的线...

越努力,越幸福! 3224

java之多线程中Thread类和Runnable接口使用方法

java提供了两种线程方式,一种是继承java.lang包下的Thread类,覆写Thread类的run()方法,在run()方法中实现运行在线程上的代码!第二种是实现Runnable接口创建多线程。下面就跟大家具体的介绍一下这两种方式! 在学习多线程之前先来看看我们熟悉的单线程程序package bean; public class Example3_2 { public s

qq_40219476的博客 1万+

【Java】创建线程的三种方式及Thread常用方法——Java多线程(一)

一、创建线程的方式 方式一:继承Thread类 1)① 新建一个类,这个类继承了Thread,此时这个实现类就是一个线程类了。② 在线程类中重写Thread类的run()方法,重写的run方法中是线程类要执行的代码。③ 当要开启新线程时,调用线程类的start()方法。 2)注意: ① 主线程与子线程:java程序中的main方法称为主线程,在main方法中调用线程类来开启的线程称为子线程。 ② 调用线程类时,使用start()方法,而不能使用run()方法。虽然执行start()方法之后,线程类同样执行的

一顿输出 2763

简述两种JAVA多线程的创建方式

一、概述 在JAVA中,用Thread类代表线程,所有线程对象,都必须是Thread类或者Thread类子类的实例。每个线程的任务就是执行一段顺序执行的代码,JAVA使用线程执行体来容纳这段代码 二、多线程的好处 1.充分利用CPU资源 2.简化代码模型 3.提高用户体验 三、创建多线程的两种方式 第一种, 通过继承Thread类创建线程类 1、定义一个类继承Thread类,并重写Thread类的run()方法,run()方法的方法体就是线程要完成的任务,因此把run()称为线程的执行体; 2、创建该类的实

m0_46660951的博客 2899
上一篇: Java 多线程1 IDEA快捷键和多线程的理解
下一篇: Java多线程3 线程的同步
wisdomcodeinside
博客等级 码龄7年 29粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值