创建线程的三种模式

news2025/6/9 13:45:16

进程,是对运行时程序的封装,是系统进行资源调度和分配的基本单位,实现了操作系统的并发。

线程,是进程的子任务,是CPU调度和分派的基本单位,实现了进程内部的并发。

线程在进程下运行。

进程之间不会影响。

不同进程很难共享数据。

同进程下的线程数据很容易共享。

进程使用内存地址可以限定用量。

继承Thread类

重写run方法:

public class Mythread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+"执行第"+i+"次..");
        }
    }
}

测试:

import java.util.*;

class Test{


    public static void main(String[] args) {
        //创建线程
        Mythread t1=new Mythread();
        Mythread t2=new Mythread();
        Mythread t3=new Mythread();
        //设置线程名
        t1.setName("线程1");
        t2.setName("线程2");
        t3.setName("线程3");
        //启动线程
        t1.start();
        t2.start();
        t3.start();



    }

}

控制台输出片段:

线程交替执行,而并非顺序执行,说明它们使用同一资源,属于同一进程。

实现Runnable接口

并重写run方法:

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try{
                //sleep会发生异常要显示处理
                Thread.sleep(20);//暂停20毫秒
            }catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "执行了"+i+"次..");

        }


    }
}

sleep():

使当前正在执行的线程暂停指定的毫秒数,也就是进入休眠的状态。

需要注意的是,sleep 的时候要对异常进行处理。

测试:

import java.util.*;

class Test{


    public static void main(String[] args) {
        //创建Runnable
        MyRunnable myRunnable = new MyRunnable();
        //创建线程,设置名称
       Thread t1=new Thread(myRunnable,"线程1");
        Thread t2=new Thread(myRunnable,"线程2");
        Thread t3=new Thread(myRunnable,"线程3");


        //启动线程
        t1.start();
        t2.start();
        t3.start();



    }

}

控制台输出片段:

join()等待这个线程执行完才会轮到后续线程得到cpu的执行权,使用这个也要抛出异常。

测试:

import java.util.*;

class Test{


    public static void main(String[] args) {
        //创建Runnable
        MyRunnable myRunnable = new MyRunnable();
        //创建线程,设置名称
       Thread t1=new Thread(myRunnable,"线程1");
        Thread t2=new Thread(myRunnable,"线程2");
        Thread t3=new Thread(myRunnable,"线程3");


        //启动线程
        t1.start();
        try {
            t1.join(); //等待t1执行完才会轮到t2,t3抢
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t2.start();
        t3.start();



    }

}

控制台输出片段:

 setDaemon():

将此线程标记为守护线程,准确来说,就是服务其他的线程,像 Java 中的垃圾回收线程,就是典型的守护线程。

import java.util.*;

class Test{


    public static void main(String[] args) {
        //创建Runnable
        MyRunnable myRunnable = new MyRunnable();
        //创建线程,设置名称
       Thread t1=new Thread(myRunnable,"线程1");
        Thread t2=new Thread(myRunnable,"线程2");
        Thread t3=new Thread(myRunnable,"线程3");

       t1.setDaemon(true);
       t2.setDaemon(true);
        //启动线程
        t1.start();
        t2.start();
        t3.start();



    }

}

控制台输出片段:

如果其他线程都执行完毕,main 方法(主线程)也执行完毕,JVM 就会退出,也就是停止运行。如果 JVM 都停止运行了,守护线程自然也就停止了。

实现Runable接口比继承Thread方法好,避免了Java单继承的局限性;适合多个相同的程序代码去处理同一资源的情况,把线程、代码和数据有效的分离,更符合面向对象的设计思想。

实现Callable接口

重写call()方法,这种方式可以通过FutureTask获取任务执行的返回值 :

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class CallerTask implements Callable<String > {
    @Override
    public String call() throws Exception {
        return "正在运行..";
    }

    public static void main(String[] args) {
        //创建异步任务
        FutureTask<String>task=new FutureTask<>(new CallerTask());
        //启动线程
        new Thread(task).start();
        try{
            //等待执行完成,返回获取结果
            String res=task.get();
            System.out.println(res);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

控制台输出:

 

重写run方法原因:

封装被线程执行的代码。

run()和start()区别:

run():封装线程执行的代码,直接调用相当于调用普通方法。

start():启动线程,然后由JVM 调用此线程的run() 方法。

Java线程周期:

 

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

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

相关文章

从0到1一步一步玩转openEuler--09 openEuler基础配置--设置日期和时间

文章目录9 设置日期和时间9.1 使用timedatectl命令设置9.1.1 显示日期和时间9.1.2 通过远程服务器进行时间同步9.1.3 修改日期9.1.4 修改时间9.1.5 修改时区9.2 使用date命令设置9.2.1 显示当前的日期和时间9.2.2 修改时间9.2.3 修改日期9.3 使用hwclock命令设置9.3.1 硬件时钟…

QT之OpenGL深度测试

QT之OpenGL深度测试1. 深度测试概述1. 1 提前深度测试1.2 深度测试相关函数2. 深度测试精度2.1 深度冲突3. Demo4. 参考1. 深度测试概述 在OpenGL中深度测试(Depth Testing)是关闭的&#xff0c;此时在渲染图形时会产生一种现象后渲染的会把最先渲染的遮挡住。而在启用深度测试…

浏览器的底层运行机制

一、复习 1.进程和线程 进程&#xff1a;指一个程序(或浏览器打开一个页面就是开辟一个进程)* 线程&#xff1a;程序中具体执行任务的一个进程中可能包含一到多个线程&#xff01;&#xff01;* 单线程&#xff1a;同时只能处理一件事&#xff0c;上一件事处理完&#xff0c;…

ASEMI三相整流模块MDS55-16特征,MDS55-16应用

编辑-Z ASEMI三相整流模块MDS55-16参数&#xff1a; 型号&#xff1a;MDS55-16 最大重复峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;1600V 最大RMS电桥输入电压&#xff08;VRMS&#xff09;&#xff1a;1700V 最大平均正向整流输出电流&#xff08;IF&#xf…

MySQL架构图

MySQL架构图 Mysql逻辑架构图主要分三层&#xff1a; 1) 第一层负责连接处理&#xff0c;授权认证&#xff0c;安全等等 每个客户端连接都会在服务器进程中拥有一个线程&#xff0c;服务器维护了一个线程池&#xff0c;因此不需要为每一个新建的连接创建或者销毁线程。 当客户…

看板管理对项目管理有什么帮助?

在目前市面上的项目管理工具中&#xff0c;项目看板功能基本上成为了标配。看板作为敏捷的项目管理工具&#xff0c;可以帮助我们将项目工作可视化展现。项目看板的作用1&#xff0c;提高团队信息流动性&#xff1a;看板工具可以及时的传递项目工作中的最新讯息&#xff0c;保证…

Mapper文件注入问题

Mapper文件注入问题UserMapper that could not be found.原因分析解决方案程序正常运行&#xff0c;但是注入类爆红问题原因分析解决方法UserMapper’ that could not be found. 原因分析 撰写了mapper文件&#xff0c;但是没有注入spring容器 解决方案 添加mybatis.mapper-…

DVWA—CSRF-Medium跨站请求伪造中级

注意&#xff1a; 1、这里对XSS(Stored)关卡不熟悉的可以从这里去看http://t.csdn.cn/ggQDK 2、把难度设置成 Medium 一、这一关同样我们需要埋下伏笔&#xff0c;诱使用户点击来提交&#xff0c;首先从XSS&#xff08;Stored&#xff09;入手。 注意&#xff1a;在前面介绍…

黑马】后台项目171集

将近一个月没有练习了&#xff0c;找到之后果然打不开出了问题【问题】运行代码打开网页后&#xff0c;发现不能正常登录&#xff0c;一开始还以为是密码记错了&#xff0c;后来发现是数据库没有正常启动&#xff0c;phpstudy中的数据库一直是启动状态&#xff0c;关闭不了。【…

这个神器,让 Python 爬虫如此简单

相信大家应该都写过爬虫&#xff0c;简单的爬虫只需要使用 requests 即可。遇到复杂的爬虫&#xff0c;就需要在程序里面加上请求头和参数信息。类似这种&#xff1a; 我们一般的步骤是&#xff0c;先到浏览器的网络请求中找到我们需要的请求&#xff0c;然后将请求头和参数信…

【运筹优化】带时间窗约束的车辆路径规划问题(VRPTW)详解 + Python 调用 Gurobi 建模求解

文章目录一、概述1.1 VRP 问题1.2 CVRP 问题1.3 VRPTW 问题二、VRPTW 的一般模型三、Python 调用 Gurobi 建模求解3.1 Solomn 数据集3.2 完整代码3.3 运行结果展示3.3.1 测试案例&#xff1a;c101.txt3.3.2 测试案例&#xff1a;r101.txt一、概述 1.1 VRP 问题 车辆路径规划问…

一场深度的IT效率革命:低代码市场加速嬗变

尽管IT技术支撑了全球的信息化浪潮&#xff0c;然而困扰行业已久的软件开发效率却难以像摩尔定律一样快速提升&#xff0c;甚至已经成为了一种瓶颈&#xff0c;在困扰着行业的继续发展。一边是码农们高喊着996的境况&#xff0c;另一边是程序员的生产力并没有用在更具价值的生产…

Qml学习——布局

最近在学习Qml&#xff0c;但对Qml的各种用法都不太熟悉&#xff0c;总是会搞忘&#xff0c;所以写几篇文章对学习过程中的遇到的东西做一个记录。 学习参考视频&#xff1a;https://www.bilibili.com/video/BV1Ay4y1W7xd?p1&vd_source0b527ff208c63f0b1150450fd7023fd8 目…

C++ 浅谈之 STL List

C 浅谈之 STL List HELLO&#xff0c;各位博友好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 这里是 C 浅谈系列&#xff0c;收录在专栏 C 语言中 &#x1f61c;&#x1f61c;&#x1f61c; 本系列阿呆将记录一些 C 语言重要的语法特性 &#x1f3c3;&am…

如何在Visual Studio、Clion、Msys2中安装和使用vcpkg

首先事情是在安装了Msys2之后&#xff0c;想在Clion中使用安装在Msys2中的vcpkg。但是折腾了很久还是无法解决。于是就折腾出了这篇文章&#xff0c;和下一篇如何在Clion使用vcpkg的文章。 不过&#xff0c;由于我电脑上已近配置好了vcpkg以及环境变量&#xff0c;要是重新删除…

【C】ASCII 的十六进制字符转文件

概述 本项目是我自己使用的 来源于用串口传文件数据到电脑进行分析的时候,需要转换成可以打开的文件 而常用的串口助手大都没有直接保存为二进制文件的功能 也完全可以当作c语言初学者的练习项目(很简单) 需求 用串口传来的文件是如下格式(ASCII字符) 需要将其转化为二进制数据…

Netty相关面试题

文章目录TCP、UDP的区别&#xff1f;同步与异步、阻塞与非阻塞的区别&#xff1f;BIO、NIO、AIO分别是什么&#xff1f;Netty跟Java NIO有什么不同&#xff0c;为什么不直接使用JDK NIO类库&#xff1f;Netty的粘包/拆包是怎么处理的&#xff0c;有哪些实现&#xff1f;说说Net…

网络安全的就业及发展前景如何?

网络空间安全专业简称“网络安全专业”&#xff0c;主要以信息构建的各种空间领域为主要研究对象&#xff0c;包括网络空间的组成、形态、安全、管理等。该专业致力于培养“互联网”时代能够支撑和引领国家网络空间安全领域的具有较强的工程实践能力&#xff0c;系统掌握网络空…

完美!终于有人把《数据结构与算法》讲透彻了(附源码笔记),复杂的问题变简单了

开篇 数据结构是计算机科学与技术专业非常重要的一门核心基础课&#xff0c;计算机科学各个领域以及各种应用软件都要使用相关的数据结构和算法。 本篇的主要目的不是提供关于数据结构和算法的定理及证明。本书采用的模式是利用不同的复杂度改善问题的解决(对于每个问题&…

Spring面试重点(一)——Spring容器

Spring容器 手写Autowired注解 /** 实现spring的Autowired注解 **/ //运行时触发 Retention(RetentionPolicy.RUNTIME) //作用于变量 Target(ElementType.FIELD) public interface Autowired {}public class UserController {Autowiredprivate UserService userService;/*** …