并发编程修炼二:创建线程

【python内功修炼011】:Python进程池和线程池详解 文章目录一、关于线程池\进程池介绍1.1 池的概念1.2 池的划分1.3 线程池和进程池的区别1.5 进程池的创建(流程)二、创建线程池\进程池的两种方法2.1 concurrent和multiprocessing区别三、concurrent.futures模块3.1 模块的介绍3.2 Executor.submit 创建进程/线程池四、concurrent.futures 常用模块4.1 Exe... 阅读详情

作者:海子

转载出处
http://www.cnblogs.com/dolphin0520/p/3913517.html

目录
  一.Java中关于应用程序和进程相关的概念

  二.Java中如何创建线程

一.Java中关于应用程序和进程相关的概念

 在Java中,一个应用程序对应着一个JVM实例(也有地方称为JVM进程),一般来说名字默认为java.exe或者javaw.exe(windows下可以通过任务管理器查看)。Java采用的是单线程编程模型,即在我们自己的程序中如果没有主动创建线程的话,只会创建一个线程,通常称为主线程。但是要注意,虽然只有一个线程来执行任务,不代表JVM中只有一个线程,JVM实例在创建的时候,同时会创建很多其他的线程(比如垃圾收集器线程)。

  由于Java采用的是单线程编程模型,因此在进行UI编程时要注意将耗时的操作放在子线程中进行,以避免阻塞主线程(在UI编程时,主线程即UI线程,用来处理用户的交互事件)。

二.Java中如何创建线程

在java中如果要创建线程的话,一般有两种方式:
1)继承Thread类 (更简洁)
2)实现Runnable接口(避免单继承的局限性)

1.继承Thread类
  继承Thread类的话,必须重写run方法,在run方法中定义需要执行的任务。

class MyThread extends Thread{
    private static int num = 0;

    public MyThread(){
        num++;
    }

    @Override
    public void run() {
        System.out.println("主动创建的第"+num+"个线程");
    }
}

  创建好了自己的线程类之后,就可以创建线程对象了,然后通过start()方法去启动线程。注意,不是调用run()方法启动线程,run方法中只是定义需要执行的任务, 如果调用run方法,即相当于在主线程中执行run方法 ,跟普通的方法调用没有任何区别,此时并不会创建一个新的线程来执行定义的任务。

public class Test {
    public static void main(String[] args)  {
        MyThread thread = new MyThread();
        thread.start();
    }
}


class MyThread extends Thread{
    private static int num = 0;

    public MyThread(){
        num++;
    }

    @Override
    public void run() {
        System.out.println("主动创建的第"+num+"个线程");
    }
}

  在上面代码中,通过调用start()方法,就会创建一个新的线程了。为了分清start()方法调用和run()方法调用的区别,请看下面一个例子:

public class Test {
    public static void main(String[] args)  {
        System.out.println("主线程ID:"+Thread.currentThread().getId());
        MyThread thread1 = new MyThread("thread1");
        thread1.start();
        MyThread thread2 = new MyThread("thread2");
        thread2.run();
    }
}


class MyThread extends Thread{
    private String name;

    public MyThread(String name){
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("name:"+name+" 子线程ID:"+Thread.currentThread().getId());
    }
}

运行结果:
  这里写图片描述

从输出结果可以得出以下结论:

  1)thread1和thread2的线程ID不同,thread2和主线程ID相同,说明通过run方法调用并不会创建新的线程,而是在主线程中直接运行run方法,跟普通的方法调用没有任何区别;

  2)虽然thread1的start方法调用在thread2的run方法前面调用,但是先输出的是thread2的run方法调用的相关信息,说明新线程创建的过程不会阻塞主线程的后续执行。

2.实现Runnable接口

  在Java中创建线程除了继承Thread类之外,还可以通过实现Runnable接口来实现类似的功能。实现Runnable接口必须重写其run方法。

下面是一个例子:

public class Test {
    public static void main(String[] args)  {
        System.out.println("主线程ID:"+Thread.currentThread().getId());
        MyRunnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
    }
}


class MyRunnable implements Runnable{

    public MyRunnable() {

    }

    @Override
    public void run() {
        System.out.println("子线程ID:"+Thread.currentThread().getId());
    }
}

Runnable的中文意思是“任务”,顾名思义,通过实现Runnable接口,我们定义了一个子任务,然后将子任务交由Thread去执行。注意,这种方式必须将Runnable作为Thread类的参数,然后通过Thread的start方法来创建一个新线程来执行该子任务。如果调用Runnable的run方法的话,是不会创建新线程的,这根普通的方法调用没有任何区别。

  事实上,查看Thread类的实现源代码会发现Thread类是实现了Runnable接口的。

  在Java中,这2种方式都可以用来创建线程去执行子任务,具体选择哪一种方式要看自己的需求。直接继承Thread类的话,可能比实现Runnable接口看起来更加简洁,但是由于Java只允许单继承,所以如果自定义类需要继承其他类,则只能选择实现Runnable接口。

Python全栈修炼之路 | 第17篇 :并发编程(上)—— 多线程与GIL 并发编程是现代软件开发中的核心技能。Python提供了多种并发模型,包括多线程、多进程和异步IO。然而,Python的多线程有一个著名的限制——全局解释器锁(GIL),它使得多线程在CPU密集型任务中无法充分利用多核CPU。本文将深入探讨Python多线程编程、threading模块的使用、各种同步原语,以及GIL的工作原理和影响。 阅读详情

相关推荐

C++内功修炼:从内存管理到并发编程的实战进阶指南

在编程语言中,内存管理和并发编程是构建高性能、可靠系统的核心技术基础。理解内存模型、对象生命周期和指针机制,是掌握系统级编程的关键原理,这直接影响程序的稳定性和效率。通过RAII(资源获取即初始化)等设计模式,开发者可以自动化资源管理,避免内存泄漏和悬垂指针问题。在多线程环境下,互斥锁、条件变量和原子操作等技术确保了数据同步与线程安全,这对开发高并发应用具有重要价值。这些技术广泛应用于游戏引擎、高频交易系统和嵌入式开发等对性能要求严苛的场景。本文以C++为例,深入探讨智能指针、移动语义及现代并发工具的实际应

weixin_32247165的博客 256

精心修炼Java并发编程(JUC)-线程三大特性

此处的变量(Variables)与 Java 编程中所说的变量有所区别,它包括了实例字段、静态字段和构成数值对象的元素,但不包括局部变量与方法参数,因为后者是线程私有的,不会被共享,自然就不会存在竞争问题。JMM 规定了。

qq_46248151的博客 1426

【python内功修炼004】:并发编程之joinableQueue模块

JoinableQueue([maxsize])模块 创建可连接的共享进程队列。这就像是一个Queue对象,但队列允许项目的使用者通知生产者项目已经被成功处理。通知进程是使用共享的信号和条件变量来实现。

金鞍少年的博客 881

Java并发编程之线程修炼

### 前言 Java 提供了多线程编程内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 - 多线程是多任务的一种特别的形式,但多线程使用了更小的资源开销。 - 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。 一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到所有的非守护线程都结束运行后才...

波罗星的博客 345

C51单片机驱动ILI9341彩屏实战:从Proteus仿真到绘制自定义图案(附完整代码)

本文详细介绍了使用C51单片机驱动ILI9341彩屏的完整实战流程。内容涵盖硬件连接、8080并行接口时序模拟、寄存器初始化、屏幕方向设置以及基本图形绘制原理,并重点讲解了如何在Proteus仿真环境中搭建电路、调试代码,最终实现自定义图案的显示。文章提供了完整的代码示例,为嵌入式开发学习者和复古硬件爱好者提供了一套可行的解决方案。

rnn9storyteller的博客 511

人工智能100问☞第5问:什么是AI三要素?

人工智能的核心三要素是​​数据、算法和算力​​,分别作为AI的“燃料”、“大脑”和“动力”,三者协同驱动智能系统的学习、推理与决策能力。

bjdx_001的博客 1992

精心修炼Java并发编程(JUC)-线程池深度剖析

这张图展现了一个Java线程所有的状态。

qq_46248151的博客 1138

清华数据结构列车调度AC100分

两种思路(1)将目标栈的数据和待混洗的数据逐个进行比较#pragma warning(disable:4996) #include<stdio.h> #include<string.h> #define maxn 1600005 using namespace std; char a[2*maxn][5];//记录操作命令 int stack[maxn]; char pop...

hgtjcxy的博客 924

c++主线程等待子线程结束_来聊聊C++中头疼的线程、并发

点击上方“AI算法修炼营”,选择加星标或“置顶”标题以下,全是干货1. 线程在一个应用程序(进程)中同时执行多个小的部分(线程),这就是多线程。多个线程虽然共享一样的数据,但是却执行不同的任务。线程启动、创建、结束主线程执行完了,就代表整个进程执行完毕了,此时,一般情况下如果其他子线程没有执行完毕,那么这些子线程也会被操作系统终止。所以为了让子线程执行完就需要让主线程保持住。但是也有意外...

weixin_30104235的博客 5140

基于BQ24610的24V电池充电板

转自我的博客 本文的主要目的在于传播基本的阅读datasheet的能力,以及PCB设计需要注意的基本问题。 本次需要设计的是24V动力锂电池充电电路。 原理图设计 参考官方参考电路 为了快速设计电路,自然是参考官方参考电路,选择Typical Application。 做细微的参数调整 由于我们的需求是给24V的电池充电,所以需要稍微修改一下原理图,接下来需...

greedyhao的博客 1万+

Innovus ECO修复时序违例:ecoAddRepeater插Buffer原理与实战

芯片物理设计越到后期,时序收敛越依赖局部修正而非全局重跑。ECO(Engineering Change Order)作为数字后端高频操作,能在不破坏既有布局布线结果的前提下,精准修复DRV违例、hold时序问题或实现功能补丁。其中,插入Buffer或Inverter是拆解长线RC负载、改善max_transition/max_capacitance最直接的手段。Innovus提供的ecoAddRepeater命令封装了单元选择、坐标摆放和网表重连等底层细节,配合ecoRoute可快速完成绕线。合理选型Buf

weixin_31858171的博客 300

java高级程序员修炼_Java程序员修炼之并发教程(一)

Java程序员修炼之并发教程(一)作者:小爱尚计算机的使用者一直以为他们的计算机可以同时做很多事情。他们认为当其他的应用程序在下载文件,管理打印队列或者缓冲音频的时候他们可以继续在文字处理程序上工作。甚至对于单个应用程序,他们任然期待它能在在同一时间做很多事情。举个例子,一个流媒体播放程序必须能同时完成以下工作:从网络上读取数字音频,解压缩数字音频,管理播放和更新程序显示。甚至文字处理器也应该能在...

weixin_42511557的博客 199

gerrit 配置 ----Gitweb集成

此外,为了让用户能够查看任何关于 gitweb 的信息 项目中,用户必须能够阅读所有引用(包括 refs/meta/config,refs/meta/dashboards/*等)。或者,如果Gerrit通过反向代理送达,它可以 为gitweb的链接生成不同的URL(需要的) 在网页服务器上重写为)。Gerrit 代码审查可以管理和生成指向 gitweb 的超链接, 允许用户从Gerrit内容跳转到相同信息, 但由 gitweb 显示。默认为,这是 Linux 发行版上“gitweb”包的常见安装路径。

QuanQuanYuanXin的博客 1405

多线程之初级修炼

定时器是何物客户端发出请求之后,要等待服务器的响应,如果超出定时器所规定的时间,还没有响应,就不再等待,继续执行。

2502_91207865的博客 479

汽车安全新防线|基于AI的入侵检测系统开发(全网独家复现),CNN-BiLSTM融合改进篇 强化CAN总线数据感知、助力多类型入侵检测、实时响应预警、车载场景有效落地

基于AI的入侵检测系统是汽车网络安全领域的重要技术突破,能够有效应对日益复杂的网络攻击威胁。随着AI技术的不断发展和普及,AI入侵检测系统将在汽车安全领域发挥越来越重要的作用。对于汽车制造商和供应商来说,实施AI入侵检测系统不仅是保障车辆安全的需要,也是提升市场竞争力的重要手段。未来,AI入侵检测系统将成为智能汽车的标准配置,为用户提供更加安全、可靠的驾驶体验。

getusushu的博客 86

Python 爬虫实战:付费 IP 代理使用技巧与爬虫稳定性优化

付费IP代理实战指南:突破反爬与优化稳定性 本文系统讲解付费IP代理在爬虫项目中的高效应用方法。首先对比分析静态代理、动态代理和隧道代理的优缺点及适用场景,推荐高并发项目优先选择隧道代理。然后详细演示了主流代理服务商的集成方法,包括代理池的自动更新和健康检测机制。核心部分重点介绍了爬虫稳定性优化策略,如智能重试、频率控制和请求间隔优化等关键技术。最后通过压力测试验证优化效果,并提供成本控制方案,包括代理复用、错峰爬取等实用技巧。通过本教程,开发者可有效解决高并发爬虫中的IP封禁问题,显著提升系统稳定性和抗风

2503_91057718的博客 2450

《多线程×时间管理大师》——程序员的并发修炼之路!

线程是操作系统调度的最小单位。简单来说,一个线程就是一个“执行流”,它可以和其他线程同时执行不同的任务。打个比方,如果一个公司去银行办理多个业务,单靠一个人(主线程)效率低下,不如多个员工同时处理各自的事务,这就像我们用多个线程来并发处理不同任务,提高程序效率。更好地利用多核 CPU 的资源提升 IO 密集型程序的响应能力相比多进程更加轻量和高效Java 多线程虽不易,但掌握核心概念之后,其实也没那么难。

Hello World! 576

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Rust 大神之路之内功修炼第四章

本章深入探讨了Rust并发编程的核心概念,包括线程、消息传递、共享状态、智能指针和模式匹配。Rust的所有权系统确保了多线程代码的安全性和高效性。通过使用std::thread创建线程,move闭包转移所有权,以及Arc和Mutex实现线程间共享数据,开发者可以编写出安全且高效的并发代码。此外,智能指针如Box、Rc和Arc在内存管理和所有权控制中扮演了重要角色。模式匹配则提供了优雅的方式来处理线程返回的结果。通过本章的学习,开发者将能够掌握Rust并发编程的高级技巧,提升代码的性能和安全性。

web3 1154

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java武林:虚拟机之道 第六章:并肩作战 - 线程与并发

Java并发编程核心概念摘要:线程创建有Thread继承、Runnable实现和Callable接口三种方式,各具特点。线程生命周期包含新建、可运行、阻塞等多种状态转换。线程安全通过synchronized、Lock、原子变量等机制保障,其中synchronized最为基础,Lock更灵活。线程协作依靠wait/notify机制及CountDownLatch等并发工具类实现。Executor框架提供了线程池管理,包括FixedThreadPool等多种类型。Java内存模型(JMM)通过volatile解决

kongzhonghu的专栏 1016

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

【python内功修炼012】:并发编程之GIL详解

【python内功修炼012】:并发编程之GIL详解

金鞍少年的博客 530

Java并发之神修炼之路---创建多线程的三种方式

清晨,阳光明媚,秋早早地就来到了“训练室”,刚进门,只见大师飞一般地敲着键盘,空格键如拍子一样打着节奏,宛如一首美妙的音乐。秋来到了大师身旁,拿出电脑开了机,大师瞅了一眼秋,说,“上次对多线程有了一个大概的认识吧”,秋点了点头,“那今天就让你开开眼吧,见识一下启动多线程的三剑客”。 启动多线程一般由三种方式,我们常用的就两种 第一种: 继承Thread类 只见大师键锋一转,飞速的写了几行代码

涛声依旧的博客 575

在c#中用mutex类实现线程的互斥_来聊聊C++中头疼的线程、并发

点击上方“AI算法修炼营”,选择加星标或“置顶”标题以下,全是干货1. 线程在一个应用程序(进程)中同时执行多个小的部分(线程),这就是多线程。多个线程虽然共享一样的数据,但是却执行不同的任务。线程启动、创建、结束主线程执行完了,就代表整个进程执行完毕了,此时,一般情况下如果其他子线程没有执行完毕,那么这些子线程也会被操作系统终止。所以为了让子线程执行完就需要让主线程保持住。但是也有意外...

weixin_39526185的博客 572

Java修炼之道--并发编程

原作地址:https://github.com/frank-lam/2019_campus_apply 前言 在本文将总结多线程并发编程中的常见面试题,主要核心线程生命周期、线程通信、并发包部分。主要分成 “并发编程” 和 “面试指南” 两 部分,在面试指南中将讨论并发相关面经。 参考资料: 《Java并发编程实战》 第一部分:并发编程 1. 线程状态转换 新建(New) 创建后尚未启动...

weixin_30312557的博客 384

从Java线程到Go协程:一个Java程序员的“轻功“修炼之路

在Java里,线程是"重装战士",启动一个线程就像召集一个特种兵,成本高、数量有限,还得小心翼翼地管理。而在Go里,协程是"轻功高手",轻轻一跃就能创建成千上万个,跑得飞快,还不怎么占资源。今天,我就来聊聊Java线程和Go协程的区别,用最接地气的方式,帮你理解这个转变。Go的协程(Goroutine)是Go运行时(Runtime)管理的,不是操作系统线程。如果同时开1000个这样的线程,大部分线程可能都在等待网络响应,CPU却没事干,内存却被占满了。),这个线程就会被挂起,直到阻塞结束。

Java_ssmart的博客 431

Java内功修炼(3)——并发的四重境界:单例之固、生产消费之衡、定时之准、池化之效

用于协调多个线程或进程之间的任务分配与数据处理。生产者负责生成数据或任务,消费者负责处理这些数据或任务,二者通过共享的缓冲区(队列)进行解耦,避免直接依赖核心作用1.解耦生产与消费逻辑:生产者仅负责生成数据并放入缓冲区,消费者仅从缓冲区获取数据并处理。两者无需直接交互,降低代码复杂度,提高模块化程度2.平衡处理速率差异:生产者与消费者通常以不同速度运行。缓冲区作为中间层,允许生产者持续写入数据,消费者按自身能力消费,避免互相阻塞3.削峰填谷:通过缓冲队列平滑流量波动,避免系统因瞬时高负载崩溃。

2401_89167985的博客 8133

Java程序员修炼之并发教程(一)

计算机的使用者一直以为他们的计算机可以同时做很多事情。他们认为当其他的应用程序在下载文件,管理打印队列或者缓冲音频的时候他们可以继续在文字处理程序上工作。甚至对于单个应用程序,他们任然期待它能在在同一时间做很多事情。举个例子,一个流媒体播放程序必须能同时完成以下工作:从网络上读取数字音频,解压缩数字音频,管理播放和更新程序显示。甚至文字处理器也应该能在忙于重新格式化文本和刷新显示的情况下同时响应键盘和鼠标事件。这样的软件就被称为并发软件。 通过Java语言和Java类库对于基础并发的支持,Java平台具有完

m0_66699725的博客 131
上一篇: 并发编程修炼一:进程和线程
下一篇: 并发编程修炼三:Thread类的使用
yjgithub
博客等级 码龄11年 53粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值