在说线程之前,有必要说下线程与进程之间的关系。
附oracle官网链接:https://docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html
这里有原版的关于线程和进程的介绍,我们只简单介绍下,作为知识普及。
一.进程与线程的关系
1.进程:进程一般情况下是程序或者应用程序的同义词,是系统进行资源和调度的基本单位,是操作系统结构的基础。它有自己独立的内存空间,换句话说,它有一套私有的运行时资源。在现代面向线程的计算机结构中,进程作为了线程的容器存在,而进程变为了程序的代名词。但是要注意的是,Java虚拟机的大多数实现都是作为一个进程运行的。
2.线程:在面向线程的计算机结构中,线程有时被称为轻量级的进程。在进程中,各个线程共享进程的资源(内存和文件)。每个应用程序都至少包含一个线程。
3.为什么要使用线程进行并发程序设计?
因为相对于进程来说,线程的切换和调度的成本远远小于进程。
二.线程的生命周期
既然要说线程,就免不了说下线程的生命周期,也就是各个状态之间的转换。
可以看到,在源码Thread类中定义了一个枚举类型State,这个State就是线程生命周期中的各种状态。
根据英文注释,我们可以知道各个状态的含义,这里不细说。
附线程的状态转换图:
后续篇我们逐渐详述介绍这几种状态之间的转换过程。
三.线程的基本操作(这些都很简单,不在这里详细说)
1.新建线程
新建一个线程有两种方式:一种是继承Thread类,并重写Thread类的run方法(因为你要在run方法中实现你的业务逻辑);另外一种是实现Runnable接口。
public class ThreadDemo extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
System.out.println("继承Thread实现线程执行");
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new ThreadDemo().start();
}
}
public class RunnableDemo implements Runnable {
@Override
public void run() {
System.out.println("我的第一个线程程序!");
}
public static void main(String[] args) {
new Thread(new RunnableDemo()).start();
}
}
其实通过源码来看,实际就是一种方式,直接实现Runnable接口。我们可以看下Thread源码类中:
所以关于如何新建线程的方式的讨论可以休矣。
2.废弃方法(可以不看了)
stop方法:暴力终止,会出现数据不一致,废弃也在情理之中,被带有中断机制的方法代替了。
suspend:挂起方法,也被废弃了,是因为调用此方法后,线程挂起后不释放资源,并且线程的状态是RUNNABLE,可能会让我们误判当前的系统状态。
resume:是与suspend配套使用的,但是如果它比suspend先执行,那线程永远挂着了,图就不截了。
3.中断方法:
有关中断的有三个方法:
①Thread类中的interrupt()方法是实例方法,它可以设置线程的中断标识(也就是说并不是调用这个方法就中断了)
②配合Thread类中的实例方法isInterrupted()来判断当前调用线程是否设置了中断标识。
③Thread类中的interrupted()也是用来判断当前的中断状态,但是会清除中断标识位。
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(){
@Override
public void run() {
while(true){
System.out.println(Thread.currentThread().interrupted());
if(Thread.currentThread().isInterrupted()){
System.out.println("我被中断了!");
break;
}
}
}
};
t.start();
t.interrupt();
}
另外要注意的是,使用Thread.sleep(long xx)方法时(还有join方法,凡是报中断异常的方法),如果线程被中断,会抛出中断异常,并且标志位也会被清除。
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(){
@Override
public void run() {
while(true){
try {
System.out.println(Thread.currentThread().getName()+"|"+Thread.currentThread().isInterrupted());
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"|"+Thread.currentThread().isInterrupted());
} catch (InterruptedException e) {
e.printStackTrace();
//如果要正确处理逻辑,这里要恢复中断标志位,重新进行中断
//重新设置中断标志
Thread.currentThread().interrupt();
}
if(Thread.currentThread().isInterrupted()){
System.out.println("我被中断了!");
break;
}
}
}
};
t.start();
t.interrupt();
}
4.等待(wait)和通知(notify)
首先要知道,这两方法是Object类中的方法,也就是说任何类都继承了这两方法。
在一个线程中,当一个对象调用wait()方法后,当前线程就会等待在这个对象上。直到另外一个线程调用了obj.notify()方法后,才能解除等待。要注意的第一点,这里的对象是同一个!第二点,这个对象必须被用作监视器锁!第三点,等待的线程必须获得了监视器锁后才能执行,并不是说另一个线程执行了notify()方法后就能被唤醒了!
public class WaitNotifyDemo{
final static Object obj = new Object();
static class T1 extends Thread {
@Override
public void run() {
synchronized (obj) {
System.out.println(System.currentTimeMillis()+":T1 start!");
try {
obj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(System.currentTimeMillis()+":T1 end!");
}
}
}
static class T2 extends Thread {
@Override
public void run() {
synchronized (obj) {
System.out.println(System.currentTimeMillis()+":T2 start!");
obj.notify();
try {
Thread.sleep(2000);//为了看的明显,等待2s
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(System.currentTimeMillis()+":T2 end!");
}
}
}
public static void main(String[] args) {
new T1().start();
new T2().start();
}
}
5.线程的加入(join)和谦让(yield)
线程的加入:在一个线程A中调用线程B的join()方法,那么线程A就必须等线程B的逻辑执行完成后,才能继续往下执行自己A的逻辑。加入实际就是一起走的意思!下面例子,最后i肯定是100000.
public class ThreadJoinDemo{
public volatile static int i = 0;
static class T1 extends Thread {
@Override
public void run() {
for(i=0;i<100000;i++);
}
}
public static void main(String[] args) throws InterruptedException {
T1 t1 = new T1();
t1.start();
t1.join();
System.out.println(i);
}
}
线程资源让出-yield:Thread.yield()是一个静态的本地方法。让出的意思很明确,让出CPU资源。但是,让出了我还要争夺的!
四.线程的分类管理
1.线程的分组-线程组
给线程分个组,起个好听的名字吧,方便管理,默认新建的线程所在的线程组是创建线程的父组。
public class ThreadGroupDemo implements Runnable{
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadGroup tg = new ThreadGroup("zhaodf");
Thread t1 = new Thread(tg, new ThreadGroupDemo(), "T1");
Thread t2 = new Thread(tg, new ThreadGroupDemo(), "T2");
Thread t3 = new Thread(new ThreadGroupDemo());
t1.start();
t2.start();
t3.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getThreadGroup().getName()+"_"+Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.守护线程:守护线程守护的是谁?守护的是用户线程,用户线程不存在了,它就没有意义了,因此也就停掉了。
public class Daemon {
public static class DaemonT extends Thread{
@Override
public void run() {
while(true){
System.out.println(System.currentTimeMillis()+"_"+Thread.currentThread().getName()+"_i am alive");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
Thread t = new DaemonT();
//必须在start方法之前设置守护线程,这样t变为守护线程,而主线程main成为用户线程。当主线程休眠2秒后,守护线程也退出
//如果放在start之后,会抛出Exception in thread "main" java.lang.IllegalThreadStateException异常
t.setDaemon(true);
t.start();
System.out.println(System.currentTimeMillis()+"_"+"主线程名称:"+Thread.currentThread().getName());
Thread.sleep(2000);
}
}
3.线程的优先级:
线程的优先级并不能保证线程优先执行,这点要注意。
public class PriorityDemo{
public static class HightPriority extends Thread{
static int count = 0;
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized (PriorityDemo.class) {
count++;
if(count>10000){
System.out.println("HightPriority is complete");
break;
}
}
}
}
}
public static class LowerPriority extends Thread{
static int count = 0;
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized (PriorityDemo.class) {
count++;
if(count>10000){
System.out.println("LowerPriority is complete");
break;
}
}
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread high = new HightPriority();
Thread low = new LowerPriority();
//设置优先级并不能保证线程一定优先执行
high.setPriority(Thread.MAX_PRIORITY);
low.setPriority(Thread.MIN_PRIORITY);
high.start();
low.start();
}
}
- 大小: 34.8 KB
- 大小: 30.8 KB
- 大小: 33 KB
- 大小: 15.1 KB
- 大小: 3.8 KB
- 大小: 26.7 KB
分享到:
相关推荐
RiPr0主题的全新V5版本(原RiPr0-V2的升级版)是一款功能卓越、性能优越且速度极快的WordPress虚拟资源商城主题。它具备首页模块化布局和WP原生小工具的自由拖拽设置,以提高网站设计便捷性。此外,该主题还支持高级筛选、内置会员生态系统和多种支付接口,使网站无需依赖任何附加插件即可实现众多功能。同时,主题也支持卡密、充值和站内币等多种功能,为您的网站提供全面而有效的解决方案。
扫地机器人是一种智能家居电器,主要用于地面清洁。它通常具备自主导航、避障、清扫和吸尘等功能,部分高级产品还增加了拖地、消毒等附加功能。扫地机器人通过内置的传感器和智能算法,能够自主规划清扫路径,识别并避开障碍物,实现高效的地面清洁。 据QYResearch调研团队最新报告“全球扫地机器人市场报告2024-2030”显示,预计2030年全球扫地机器人市场规模将达到87.8亿美元,未来几年年复合增长率CAGR为7.2%。
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
VM17的密钥,亲测有效的,用的多了可能就没了
easy-interceptor修改请求头和响应头.zip
matlab机械臂关节空间轨迹规划,3-5-3分段多项式插值法,六自由度机械臂,该算法可运用到仿真建模机械臂上实时运动,可视化轨迹,有角度,速度,加速度仿真曲线。 也可以有单独角度,速度,加速度仿真曲线。 可自行更程序中机械臂与点的参数。 谢谢大家 (程序中均为弧度制参数)353混合多项式插值
pt100温度变送器,支持k型热电偶 4-20mA输出全套方案资料 2线、3线、隔离型。 (样板是2线电流 0-10V输出) 0-5V 0-10V输出 国产24位ADC精度0.01度,国产12位DAC千分之一线性价格便宜成熟方案。 485通信到串口示波器看温度电流曲线 2.4寸tft液晶屏,有串口屏接口。 外壳采用abs+透明上盖触摸按键组成。 2点仪表标定校准方式。
燕山大学数字电子技术实验报告1-5
2024年心灵状态全球报告-Six Seconds-2024-49页.pdf
Teamcenter清理缓存脚本,双击此bat,即可清理Teamcenter缓存
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
72619971-63e9-4b20-aae7-d6ce002ace9-1.zip
该课件是给人工智能专业本科生上课用ppt,自己编写的,不是教材自带的ppt(一般教材自带的ppt全是文字,根本无法授课使用)。有需要的教师可以下载使用。也适合有想要学习opencv计算机视觉的学生使用。或作为期末考试复习专用。除了需要ppt,还需要教案和讲稿的教师可以私信我留言。 内容目录如下: 第1章 OpenCV起步 OpenCV简介、配置开发环境、使用OpenCV文档和示例 第2章 图像处理基础 NumPy简介、图像基础操作、图像运算 第3章 图形用户界面 窗口控制、绘图、响应鼠标事件、使用跟踪栏 第4章 图像变换 色彩空间变换、几何变换、图像模糊、阈值处理、形态变换 第5章 边缘和轮廓 边缘检测、图像轮廓、霍夫变换 第6章 直方图 直方图基础、直方图均衡化、二维直方图 第7章 模板匹配和图像分割 模板匹配、图像分割、交互式前景提取 第8章 特征检测 角检测、特征点检测、特征匹配、对象查找 第9章 人脸检测和识别 人脸检测、人脸识别 第10章 机器学习和深度学习 机器学习、深度学习
钢材门户企业站共12个页面,整套企业站,使用html+javascript+css实现,动态网页。各页面链接已经添加。 首页预览图片:https://a.ladshow.com/other/csdn/WX20250107-150141%402x%20%281%29.png 行业咨询预览图片:https://a.ladshow.com/other/csdn/WX20250107-150153%402x%20%281%29.png
大数据lzo压缩库,jar包格式
项目建设考核评价模板.xlsx
升压变压器市场前景分析:预计2030年市场规模将达到112亿美元,潜力无限 在电力传输的广阔舞台上,升压变压器以其独特的功能和广泛的应用场景,成为了确保电能高效、安全传输的关键角色。随着全球电力需求的持续增长和新能源发电的快速发展,升压变压器市场正迎来前所未有的发展机遇。然而,面对复杂多变的市场环境和日益激烈的竞争态势,如何精准把握市场脉搏,成为每一位市场参与者关注的焦点。本文将深入探讨升压变压器市场的现状、趋势、竞争格局及咨询服务的重要性,为您揭示市场的无限潜力。 市场概况: 据QYResearch(恒州博智)统计及预测,2023年全球升压变压器市场销售额达到了67亿美元,预计2030年将达到112亿美元,年复合增长率(CAGR)为7.5%。这一数据不仅彰显了升压变压器市场的强劲增长势头,也预示着未来几年内市场将保持持续扩张的态势。在中国市场,随着电力行业的快速发展和电网建设的不断推进,升压变压器的需求量也在稳步增长。 技术创新与趋势: 技术创新是推动升压变压器市场发展的重要力量。随着新材料、新工艺的不断涌现,升压变压器的性能得到了显著提升,能效和可靠性不断提高。同时,智能化、数字化
电机与拖动技术三级项目直流电机串电阻启动项目ppt
MATLAB再生制动模型 制动能量回收模型 电动车电液复合制动模型 刹车回能模型 电机再生制动模型 目标车型:电动汽车 模型包括:轮毂电机充电模型 电池发电模型 控制策略模型 前后制动力分配模型 电液制动力分配模型 输入模型(注:控制策略模型,因此整车参数以及仿真工况等均通过AVL_Cruise中进行导入) 控制策略:最优制动能量回收策略 控制算法:逻辑门限值控制算法 通过逻辑门限值控制算法,依次分配: 前轮制动力 后轮制动力 电机制动力 液压制动力 通过控制策略与传统控制策略对比可知,最优制动能量回收策略具有一定的优越性。 单模型:可运行出仿真图,业内人士首选。 color="#ffffff ">712093537107< font> <img class="alignnone size-large" src="http: img.alicdn.com bao uploaded i3 O1CN01FvosPg1S4ROwl9tSZ_!!53-fleamarket.heic" width="1080" height="1440" > <img class="alignnone s
Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作