1. 从JDK1.5开始,Java提供了3种方式来创建,启动多线程:
Ø 继承Thread类来创建线程类,重写run()方法作为线程执行体。
Ø 实现Runnable接口来创建线程类,重写run()方法作为线程执行体。
Ø 实现Callable接口来创建线程类,重写run()方法作为线程执行体。
其中第一种方式效果最差,它有2点坏处:
l 线程类继承了Thread类,无法在继承其他父类。
l 因为每条线程都是一个Thread子类的实例,因此多个线程之间共享数据比较麻烦。
对于第二三种方式,它们的本质是一样的,只是Callable接口里包含的call()方法既可以声明抛出异常,也可以拥有返回值。
2.此外启动线程应该使用start()方法,而不是run()方法。如果程序从未调用线程对象的start()方法来启动它,那么这个线程对象将一直处于”新建”状态(1.新建 2.就绪 3.运行 4.阻塞 5.死亡总共5个状态),它永远也不会作为线程获得执行的机会,它只是一个普通的Java对象。当程序调用线程对象的run()方法时,与调用普通Java对象的普通方法并无任何区别,因此绝对不会启动一条新线程的。
3. 静态的同步方法:
Java语言规定:任何线程进入同步方法,同步代码块之前,必须先获取同步方法,同步代码块对应的同步监视器。对于同步代码块而言,程序必须显示为它指定同步监视器;对于同步非静态方法而言,该方法的同步监视器是this-即调用该方法的Java对象;对于静态的同步方法而言,该方法的同步监视器不是this,而是该类本身。
如以下代码:
class SynchronizedStatic implements Runnable { static boolean flag = true; public static synchronized void test0() {//同步监视器是该类本身 for (int i = 0; i < 1000; i++) { System.out.println("test0: " + Thread.currentThread().getName() + " " + i); } } public void test1() { synchronized (this) {//同步监视器是this,即调用该方法的Java对象。 for (int i = 0; i < 1000; i++) { System.out.println("test1: " + Thread.currentThread().getName() + " " + i); } } } public void run() { if (flag) { flag = false; test0(); } else { flag = true; test1(); } } public static void main(String args[]) throws InterruptedException { SynchronizedStatic ss = new SynchronizedStatic(); new Thread(ss).start(); Thread.sleep(1); new Thread(ss).start(); } }运行结果:
test0: Thread-0 244
test1: Thread-1 7
test0: Thread-0 245
test1: Thread-1 8
test0: Thread-0 246
test1: Thread-1 9
test0: Thread-0 247
test1: Thread-1 10
test1: Thread-1 11
test1: Thread-1 12
test0: Thread-0 248
test1: Thread-1 13
test0: Thread-0 249
test0: Thread-0 250
从运行结果可以看出:静态同步方法可以和以this为同步监视器的同步代码块同时执行。因为两者的同步监视器不一样,前者是对SynchronizedStatic类的锁定,后者是对ss变量所引用的对象的锁定,因此程序可以在两个线程间相互切换。
若将test1()方法做以下更改:
public void test1() { synchronized (SynchronizedStatic.class) {//和静态方法具有了相同的同步监视器 for (int i = 0; i < 1000; i++) { System.out.println("test1: " + Thread.currentThread().getName() + " " + i); } } }运行结果:
test0: Thread-0 995
test0: Thread-0 996
test0: Thread-0 997
test0: Thread-0 998
test0: Thread-0 999
test1: Thread-1 0
test1: Thread-1 1
test1: Thread-1 2
test1: Thread-1 3
test1: Thread-1 4
结果说明:静态同步方法和以当前类为同步监视器的同步代码块不能同时执行。
相关推荐
告别量子调试:手把手教你正确使用QtConcurrent::run和QThreadPool执行类方法
本文详细解析了Qt多线程开发中QtConcurrent::run和QThreadPool的正确使用方法,解决了类方法并发执行的常见问题。通过6个实战案例,重点讲解了this指针传递、线程安全、生命周期管理等核心技巧,帮助开发者避免量子调试困境,提升并发编程效率。特别针对Qt Concurrent模块的两种函数签名差异提供了类型安全检测表。
5 表达式中的陷阱整理
本节要点: 表达式类型自动提升的陷阱 复合赋值运算符隐含的类型转换 原始类型带来的泛型擦除 Java 不支持泛型数组 正则表达式中点号(.)匹配任意字符 不要调用线程对象的 run() 方法 静态同步方法的同步监视器是类 多线程执行环境的线程安全问题 1 JVM 对字符串的处理 先看一条创建字符串对象的代码,如下: String str = new String("hell
别再乱用QtConcurrent::run了!手把手教你区分全局线程池与自定义对象调用的正确姿势
本文深入解析QtConcurrent::run在多线程编程中的正确使用方法,重点区分全局线程池与成员函数调用的适用场景。通过原理分析、实战对比和决策模型,帮助开发者避免常见陷阱,掌握Qt并发模块的高效使用技巧,提升代码的线程安全性和性能表现。
java基础语法练习第十章
两种实现多线程方式的对比分析 1、下列关于线程的说法中,错误的是( ) A、线程就是程序 B、线程是一个程序的单个执行流 C、多线程用于实现线程并发程序 D、多线程是指一个程序的多个执行流 您提交的答案: 【A】 正确答案是:【A】 线程的生命周期及状态转换 2、 下列关于Thread类的说法中,错误的是( ) A、继承Thread类创建线程的方式可以防止出现多父类问题 B、Thread类属于java.util包 C、继承Thread的方式定义线程后,覆写的run()方法会在该线程的start()方
分享一下使用Xilinx FPGA驱动MIPI DSI LCD屏的心路历程
分享一下调试用Xilinx FPGA驱动MIPI DSI LCD屏的心路历程,看到的朋友们,可以避免继续踩坑。
中兴交换机配置SSH登录
SSH是在传统的Telnet协议基础上发展起来的一种安全的远程登录协议。发送和接收数据时, SSH会自动对数据进行加密及解密。相比于Telnet,SSH能防止“中间人”攻击、DNS欺骗、IP 欺骗等,无论是在认证方式或者数据传输的安全性上都有很大的提高。SSH用户认证方式有3种,分别为本地(Local)认证、RADIUS认证和TACACS+认证。以表规划数据为例,说明配置SSH登录的步骤。
java多线程(随堂笔记)
多线程 程序(program):是为了完成特定任务,用某种语言编写的一组指令的集合;即指一段静态的代码,静态对象; 进程(process):是程序的一次执行过程,或是正在运行的一个程序;即指一个动态的过程,有它自身的产生,存在和消亡的过程。—生命周期; 通俗点说:程序是静态的,进程是动态的; 进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域; 线程(thread):进程可进一步细化为线程,是一个程序内部的一条执行路径; 若一个进程同一时间并发执行多个线程,就是支持多线程的;
DGX Spark上PyTorch GPU环境配置实战:CUDA 13.0与ARM架构全流程
在深度学习中,CUDA作为GPU加速计算的底层基础,其版本与深度学习框架(如PyTorch)的匹配直接影响模型训练的效率与稳定性。GPU环境配置不仅涉及驱动、CUDA工具链与框架运行时的协同,还依赖于硬件架构与预构建包的兼容性。在AI开发机Ubuntu系统上,正确对齐CUDA版本、计算能力架构及安装源,是避免环境故障、发挥硬件算力的关键。无论是面向个人AI超算还是通用GPU服务器,掌握版本对齐、路径隔离与验证方法,都能大幅提升开发效率。本文以DGX Spark为例,详解从环境摸底到PyTorch GPU版本
java 多线程不执行命令_java多线程
1 什么是进程,线程进程:进程是程序执行的一个实例。它是一个动态的概念。比如说,10个用户同时执行IE,那么就有10个独立的进程(尽管他们共享同一个可执行代码)。进程的特点:每一个进程都有自己的独立的一块内存空间(独立的堆和栈,不共享堆栈)、一组资源系统。进程由操作系统调度, 进程间的切换会有较大的开销。守护进程:在系统的引导的时候会开启很多服务,这些服务就叫做守护进程,随系统关闭时终止...
【OpenClaw从入门到精通】第13篇:OpenClaw低代码编排实战:非技术人员也能玩转AI自动化流程(2026新版实测)
本文聚焦OpenClaw 2026版核心升级的低代码编排能力,针对非技术人员的实操需求,从底层逻辑、双环境部署、三类实战案例、避坑指南四个维度展开。详解阿里云集群版(企业级)与汉化本地版(个人调试)的部署步骤,通过基础数据统计、公众号内容生产线、企业级任务调度三个递进式案例,演示可视化拖拽搭建自动化流程的完整过程。全程零代码/低代码操作,配套详细参数配置、执行结果模拟及问题排查方案,帮助销售、运营、自媒体等非技术人员快速掌握自动化工具,将重复工作交给AI,提升核心工作效率。
【STM32项目】基于stm32智能鱼缸控制系统的设计与实现(完整工程资料源码)
随着现代化经济的快速发展,物质条件富足的人开始追求精神富足,越来越多的人通过饲养观赏鱼来充实生活、释放压力,但并非所有饲养者都有时间和经验来管理好鱼缸。一种由单片机控制,可实时检测和调节鱼缸环境,可把鱼缸环境实时反映给用户并能被用户远程操控的系统,可以解决养鱼成活率低、耗费时间和精力、参与感不强等诸多难题。
java基础总结(面试高频问题)一:多线程创建的四种方式,线程安全(线程同步),start和run的区别
前言:最近在做java基础的总结工作,决定把这些java基础中的面试高频考点写出来,方便自己复习,也方便和我一样的新手查阅;笔者之前一直在做android端的opencv图像处理项目,但是由于项目的保密性,截止到上一篇博客,只更新到Android中配置opencv这一步,具体的功能实现会放到后续逐步更新出来; 话不多说,开始总结: 1:java创建多线程有三种方式: (1): 第一种,通过继承Thread类创建线程类 通过继承Thread类来创建并启动多线程的步骤如下: 1、定义一个类继承Thread类,并
48-OpenCVSharp —-Cv2.MatchTemplate() 函数功能(模板匹配)详解
是 OpenCV 中一个常见且简单的模板匹配算法,适用于目标检测和图像识别中的静态场景。它的优点是易于理解和实现,但在面对旋转、尺度变化、复杂背景或光照变化等挑战时,效果可能大打折扣。在这些情况下,结合多尺度图像、特征匹配算法(如 SIFT、SURF、ORB 等)以及深度学习模型可以显著提高匹配的鲁棒性和精度。模板匹配仍然是一个非常基础但强大的工具,适用于一些简单的图像匹配任务。对于更加复杂和动态的图像识别任务,我们通常会使用其他更加复杂的算法或者深度学习模型来处理。
Java表达式的陷阱——多线程的陷阱
6、多线程的陷阱 Java语言提供了非常优秀的多线程支持,使得开发者能以简单的代码来创建、启动多线程,而且Java语言内置了多线程支持极好地简化了多线程编程。虽然如此,Java多线程编程中依然存在一些容易混淆的陷阱。 6、1 不要调用run()方法 从Java5开始,Java提供了三种方式来创建、启动多线程。 继承Thread类创建线程类,重写run()
从“点云”到“图像”:华为896线激光雷达的技术飞跃与行业影响浅析
华为发布全球首款896线双光路激光雷达,实现车载感知从"3D点云"到"3D成像"的跨越。该产品采用创新双光路架构,集成广角和长焦单元,单帧点云量达128线产品的7倍,可在55米外识别小狗摇尾巴等细节。实测数据显示,其能识别120米外14厘米低矮障碍物,夜间低反射率目标识别距离提升190%。尽管速腾聚创随后发布更高线数产品,但华为强调实用性和量产可行性,成本仅增加1-2万元。这一突破标志着激光雷达进入大规模应用阶段,将加速高阶智驾功能普及,强化华为在智能汽车领域的技术底
AEJoy —— 表达式之仅限在某一维摆动【JS】
效果图 wiggle() 的作用仅限于水平方向 想法 wiggle() 确实是一个非常方便的工具,但有时您希望对它有更多的控制。在本例中,我们希望仅将摆动限制在水平方向。 设计 要理解 wiggle() 最重要的一点是,它生成的结果与应用它的属性具有相同的维度。例如,如果你将 wiggle() 应用于 3D 层的 position 属性,结果将是一个由三个元素组成的数组(x、y 和 z 各一个)。我们需要做的就是将 wiggle() 的结果捕捉到一个变量(我们称之为 “w” ),然后从这个变量中提取我们想
多线程的陷阱
1.有一个线程类对象(通过继承Thread类来实现),如果程序从未调用过该对象的start()方法来启动它,那么这个线程对象将一直处于“新建“状态,它永远不会作为线程获得执行的机会,只是一个普通的java对象,这时,直接调用其run()方法时,与普通的java对象的普通方法并没有什么区别。 2.静态方法通过加synchronized关键字来实现同步,则此时该方法锁定的对象是当前这个类,即XXX....
文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况
主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。
C++构造函数中静态局部变量的多线程陷阱与解决方案
在C++编程中,静态局部变量因其在函数调用间保持状态的特性,常被用于实现计数器、缓存等场景。其核心原理在于拥有静态存储期但局部作用域,生命周期贯穿程序运行。然而,在多线程环境下,这种设计会引发严重的数据竞争和线程安全问题。C++11标准虽然保证了静态局部变量初始化本身的线程安全,但对其后续的读写操作并未提供同步保障,这正是多线程编程中常见的隐患之一。从工程实践角度看,这类问题在高并发场景下尤为突出,可能导致对象ID重复、状态不一致等难以调试的Bug。本文通过具体案例分析,深入探讨了在构造函数中使用静态局部变
VB摄像头监控
该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制
NTscan扫描工具
ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。
Qt/C++多线程同步实战:从互斥锁到信号槽的完整指南
多线程编程是现代软件开发中的核心概念,旨在解决单线程程序在处理耗时任务时界面卡顿、响应迟缓的问题。其基本原理是通过创建多个执行流并发运行,提升CPU利用率和程序响应性。在C++开发中,线程同步技术确保了多个线程安全、有序地访问共享资源,避免数据竞争和未定义行为,这对于构建稳定、高效的桌面应用、嵌入式系统和服务器后台至关重要。Qt框架作为跨平台C++开发的利器,提供了丰富的同步原语和独特的基于事件循环的线程通信机制。在实际应用场景中,开发者需要根据具体需求选择合适的同步工具——例如,使用QMutex保护临界区
OV9734 DATASHEET,完整规格书
OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等
Java高级基础知识之多线程(一)
多线程创建的方法 方法一:继承Thread类的方法 创建一个继承于Thread类的子类 重写Thread类中的run()方法,将此线程执行的操作,声明在run()中 创建Thread类的子类的对象 通过此对象调用start(); 注意:不可以调用run方法不然还是单线程 注意:start方法只可以调用一次(启动一个线程不可以让已经拥有的start再次调用,如需调用再次创建一个线程对象) 以下为例子: Thread类的常见方法 start();启动当前线程调用线程中的ru..
ABAP同步与异步调用:核心概念、实战场景与性能优化指南
在软件工程中,程序调用模式是影响系统性能和响应能力的基础技术概念。同步调用采用阻塞式设计,调用方必须等待被调用方执行完毕才能继续,其原理简单直接,确保了执行顺序的严格性和数据一致性,适用于流程强依赖或轻量级操作场景。异步调用则采用非阻塞式设计,调用方发起请求后立即返回,被调用方在后台独立执行,其核心价值在于提升资源利用率和系统吞吐量,尤其适合处理耗时操作或需要保持前端响应的应用场景。在SAP ABAP开发领域,理解同步与异步调用的本质区别及适用边界,是构建高效企业应用的关键。本文聚焦ABAP中的同步调用(如
闭包延迟绑定陷阱详解
本文从现象出发,拆解这个 Python 经典陷阱 —— 闭包延迟绑定(Late Binding)。
Java多线程练习三
本文介绍了Java中线程命名与获取线程名称的方法。主要内容包括: 两种设置线程名称的方式:通过Thread构造函数直接命名和使用setName()方法间接命名 获取当前线程名称的方法:使用Thread.currentThread().getName() 对比了Thread.start()和Thread.run()的区别:前者创建新线程并执行run()方法,后者只是普通方法调用 通过代码示例展示了每种方法的具体实现,帮助理解线程命名的实际应用场景以及多线程执行机制的差异。这些方法对于提高代码可读性和调试效率很
C# 构造函数与析构函数:5个关键执行顺序陷阱与内存泄漏排查
模式的正确使用,直接影响着应用程序的性能和稳定性。本文将深入探讨这些关键方法的执行顺序陷阱,并通过实际案例展示如何避免内存泄漏。掌握这些对象生命周期管理技术后,你将能够构建更健壮、高效的C#应用程序。记住,良好的资源管理习惯往往比事后调试更能提升代码质量。在C#开发中,对象生命周期管理是每个中高级开发者必须掌握的技能。构造函数、静态构造函数、析构函数以及。注意:静态构造函数在类型首次被访问时执行且仅执行一次,而实例构造函数每次创建新对象时都会执行。提示:静态构造函数应保持简单,避免复杂逻辑和阻塞操作。
车载C#多线程安全危机:1个未加锁Task.Run竟致ADAS误触发——真实事故复盘
直击车载C#多线程安全痛点,详解Task.Run误用导致ADAS误触发的真实事故复盘。本车载C#开发教程覆盖CAN通信、实时任务调度与lock/async锁机制实践,提升系统可靠性。适合智能驾驶软件工程师快速避坑,值得收藏。
Flask多线程配置避坑指南:为什么你的app.run(threaded=True)不生效?
本文深入解析Flask多线程配置的常见问题与解决方案,揭示为何`app.run(threaded=True)`可能不生效的原因。从版本兼容性、调试模式限制到生产环境部署,提供完整的避坑指南和性能优化策略,帮助开发者提升Flask应用的并发处理能力。
213



被折叠的 条评论
为什么被折叠?



