java 多线程学习笔记之 线程实现(线程阻塞)

2023-11-20

java 实现线程方法主要分为两种方法:一种是继承:java.lang.Thread, 另一种实现java.lang.Runnable接口。


对于直接继承Thread 的类来说,代码大致框架是:

public class MyThread extends Thread{

         //覆写run()方法
         public void run(){
                   //other code  
         }
}


对于实现Runnabel 接口来说,代码大致框架是:

public class MyRunnable implements Runnable{

         //实现run() 方法
         public void run(){
                   //other code
          }

}

线程状态

新生状态(New): 当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后,此时该线程处于新生(new)状态,处于新生状态的线程有自己的内存空间,但该线程并没有运行,此时线程还不是活着的(not alive);

         就绪状态(Preper): 通过调用线程实例的start()方法来启动线程使线程进入就绪状态(runnable);处于就绪状态的线程已经具备了运行条件,但还没有被分配到CPU即不一定会被立即执行,此时处于线程就绪队列,等待系统为其分配CPCU,等待状态并不是执行状态; 此时线程是活着的(alive);

   运行状态(Running): 一旦获取CPU(被JVM选中),线程就进入运行(running)状态,线程的run()方法才开始被执行;在运行状态的线程执行自己的run()方法中的操作,直到调用其他的方法而终止、或者等待某种资源而阻塞、或者完成任务而死亡;如果在给定的时间片内没有执行结束,就会被系统给换下来回到线程的等待状态;此时线程是活着的(alive);

  阻塞状态(Blocked):通过调用join()、sleep()、wait()或者资源被暂用使线程处于阻塞(blocked)状态;处于Blocking状态的线程仍然是活着的(alive)

死亡状态(Dead):当一个线程的run()方法运行完毕或被中断或被异常退出,该线程到达死亡(dead)状态。此时可能仍然存在一个该Thread的实例对象,当该Thready已经不可能在被作为一个可被独立执行的线程对待了,线程的独立的call stack已经被dissolved。一旦某一线程进入Dead状态,他就再也不能进入一个独立线程的生命周期了。对于一个处于Dead状态的线程调用start()方法,会出现一个运行期(runtime exception)的异常;处于Dead状态的线程不是活着的(not alive)。



相关见解:

1、程序通过Thread t = new Thread(),调用t.start()启动一个线程,使该线程进入可运行(Runnable)的状态。

2、JVM去调度(Scheduler) 在可运行状态(Runnable)下的线程,使该线程处于运行 (Running) 状态,由于JVM的调度会出现不可控性,即不是优先级高的先被调用,可能先调用,也可能后调用的的情况。(并不依赖优先级

相关演示代码:

package com.example.main;

import com.examplex.threadstate.MyThread;

public class TestMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread thread1 = new MyThread("线程一");
		MyThread thread2 = new MyThread("线程二");
		MyThread thread3 = new MyThread("线程三");
		MyThread thread4 = new MyThread("线程四");

		// 测试线程等级
		thread1.setPriority(Thread.MAX_PRIORITY);
		thread2.setPriority(Thread.MIN_PRIORITY);
		thread3.setPriority(Thread.NORM_PRIORITY);
		thread4.setPriority(Thread.NORM_PRIORITY);

		thread1.start();
		thread2.start();
		thread3.start();
		thread4.start();

	}

}
package com.examplex.threadstate;

public class MyThread extends Thread {
	// 线程名称
	private String threadname;

	public String getThreadname() {
		return threadname;
	}

	public void setThreadname(String threadname) {
		this.threadname = threadname;
	}

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

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("我是自定义线程" + this.threadname);
	}

}

3、线程 运行状态 (Running) 下,调用礼让 yield() 方法,可以使线程回到可运行状态 (Runnable) 下,等待 JVM 的再次调度(让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中)

结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。
相关测试代码:

package com.examplex.threadstate;

public class MyRunnable implements Runnable {
	private String runnablename;

	public String getRunnablename() {
		return runnablename;
	}

	public void setRunnablename(String runnablename) {
		this.runnablename = runnablename;
	}

	public MyRunnable(String runnablename) {
		this.runnablename = runnablename;
	}

	@Override
	public void run() {

		System.out.println("我是自定义线程:" + this.runnablename + "已獲得JVM調用");
		System.out.println("我是自定义线程:" + this.runnablename);

	}

}

package com.examplex.threadstate;

public class MyThread extends Thread {
	// 线程名称
	private String threadname;

	public String getThreadname() {
		return threadname;
	}

	public void setThreadname(String threadname) {
		this.threadname = threadname;
	}

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

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("我是自定义线程:" + this.threadname + "已獲得JVM調用");
		yield();
		System.out.println("我是自定义线程:" + this.threadname);
	}

}
package com.example.main;

import com.examplex.threadstate.MyRunnable;
import com.examplex.threadstate.MyThread;

public class TestMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread thread1 = new MyThread("线程一");
		MyRunnable thread2 = new MyRunnable("線程二");
		Thread thread = new Thread(thread2);
		// 設置線程優先級
		thread1.setPriority(Thread.MAX_PRIORITY);

		// 测试線程yield方法
		thread1.start();
		thread.start();

	}

}
相关截图:


4、线程在Running的过程中可能会遇到阻塞(Blocked)情况
①.调用join()sleep()方法,sleep()时间结束或被打断,join()中断都会回到Runnable状态,等待JVM的调度。

相关测试代码:

package com.examplex.threadstate;

public class MyRunnable implements Runnable {
	private String runnablename;

	public String getRunnablename() {
		return runnablename;
	}

	public void setRunnablename(String runnablename) {
		this.runnablename = runnablename;
	}

	public MyRunnable(String runnablename) {
		this.runnablename = runnablename;
	}

	@Override
	public void run() {

		System.out.println("我是自定义线程:" + this.runnablename + "已獲得JVM調用");		
		System.out.println("我是自定义线程:" + this.runnablename);

	}

}
package com.examplex.threadstate;

public class MyThread extends Thread {
	// 线程名称
	private String threadname;

	public String getThreadname() {
		return threadname;
	}

	public void setThreadname(String threadname) {
		this.threadname = threadname;
	}

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

	@Override
	public void run()  {
		// TODO Auto-generated method stub
		System.out.println("我是自定义线程:" + this.threadname + "已獲得JVM調用");	
		try{
		join(1000);  //此處也可為sleep()方法。
		}catch(Exception e){
			e.printStackTrace();
		}
		System.out.println("我是自定义线程:" + this.threadname);
	}

}

package com.example.main;

import com.examplex.threadstate.MyRunnable;
import com.examplex.threadstate.MyThread;

public class TestMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread thread1 = new MyThread("线程一");
		MyRunnable thread2 = new MyRunnable("線程二");
		Thread thread = new Thread(thread2);
		// 設置線程優先級
		thread1.setPriority(Thread.MAX_PRIORITY);

		// 测试線程yield方法
		thread1.start();		
		thread.start();

	}

}
相关截图展示:



以上文件已经讲解了线程阻塞的实现方法【yield、sleep、join】和线程优先级问题,下一件多线程,主要讲解线程同步于互斥。




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 多线程学习笔记之 线程实现(线程阻塞) 的相关文章

  • Java线程:volatile关键字

    本文转载至 http lavasoft blog 51cto com 62575 222076 Java线程 volatile关键字 Java 语言包含两种内在的同步机制 同步块 或方法 和 volatile 变量 这两种机制的提出都是为了
  • java并发包:读写锁

    本文转载至 http blog csdn net a910626 article details 51900954 ReadWriteLock是jdk5中提供的读写分离锁 读写分离锁可以有效的帮助减少锁竞争 以提升性能 用锁分离的机制来提升
  • Java线程:线程的同步-同步方法

    本文转载至 http lavasoft blog 51cto com 62575 221914 Java线程 线程的同步 同步方法 线程的同步是保证多线程安全访问竞争资源的一种手段 线程的同步是Java多线程编程的难点 往往开发者搞不清楚什
  • Java线程:线程的交互

    本文转载至 http lavasoft blog 51cto com 62575 99157 线程交互是比较复杂的问题 SCJP要求不很基础 给定一个场景 编写代码来恰当使用等待 通知和通知所有线程 一 线程交互的基础知识 SCJP所要求的
  • Java线程:线程栈模型与线程的变量

    本文转载至 http lavasoft blog 51cto com 62575 99152 要理解线程调度的原理 以及线程执行过程 必须理解线程栈模型 线程栈是指某时刻时内存中线程调度的栈信息 当前调用的方法总是位于栈顶 线程栈的内容是随
  • Java线程:新特征-障碍器

    本文转载至 http lavasoft blog 51cto com 62575 222738 Java5中 添加了障碍器类 为了适应一种新的设计需求 比如一个大型的任务 常常需要分配好多子任务去执行 只有当所有子任务都执行完成时候 才能执
  • java并发包:概论

    本文转载至 http blog csdn net a910626 article details 51900917 为什么要学习并发 今天和一哥们聊天 聊着聊着聊到钱的方面 当时我就说 全世界60亿人 要是每人给我一块钱那不就发财了啊 哥们
  • Java线程:并发协作-死锁

    本文转载至 http lavasoft blog 51cto com 62575 222074 Java线程 并发协作 死锁 线程发生死锁可能性很小 即使看似可能发生死锁的代码 在运行时发生死锁的可能性也是小之又小 发生死锁的原因一般是两个
  • Java线程:新特征-有返回值的线程

    本文转载至 http lavasoft blog 51cto com 62575 222082 在Java5之前 线程是没有返回值的 常常为了 有 返回值 破费周折 而且代码很不好写 或者干脆绕过这道坎 走别的路了 现在Java终于有可返回
  • java 多线程学习笔记之 线程互斥

    许多线程共享同一数据 这种情况在现实的生活中也是经常发生的 比如火车站的火车票售票系统 火车票售票系统是一个常年运行的系统 为了满足乘客的需求 我们不能只设一个窗口 必须设很多的售票窗口 每个售票窗口就像一个线程 它们各自运行 共同访问相同
  • Java线程:新特征-信号量

    本文转载至 http lavasoft blog 51cto com 62575 222469 Java线程 新特征 信号量 Java的信号量实际上是一个功能完毕的计数器 对控制一定资源的消费与回收有着很重要的意义 信号量常常用于多线程的代
  • Java线程:线程的调度-守护线程

    本文转载至 http lavasoft blog 51cto com 62575 221845 Java线程 线程的调度 守护线程 守护线程与普通线程写法上基本么啥区别 调用线程对象的方法setDaemon true 则可以将其设置为守护线
  • java并发包:生产者消费者模式

    本文转载至 http blog csdn net a910626 article details 51900974 生产者消费者模式是一个经典的多线程设计模式 它为多线程间的协作提供了良好的解决方案 在生产者消费者模式中 通常有两类线程 即
  • Java线程:线程状态的转换

    本文转载至 http lavasoft blog 51cto com 62575 99153 一 线程状态类型 1 新建状态 New 新创建了一个线程对象 2 就绪状态 Runnable 线程对象创建后 其他线程调用了该对象的start 方
  • java并发包:重入锁与Condition条件

    本文转载至 http blog csdn net a910626 article details 51900941 重入锁 这里介绍一下synchronized wait notify方法的替代品 或者说是增强版 重入锁 重入锁是可以完全替
  • java 多线程学习笔记之 线程同步

    在前面我们将了很多关于同步的问题 然而在现实中 需要线程之间的协作 比如说最经典的生产者 消费者模型 当队列满时 生产者需要等待队列有空间才能继续往里面放入商品 而在等待的期间内 生产者必须释放对临界资源 即队列 的占用权 因为生产者如果不
  • Java线程:新特征-阻塞栈

    本文转载至 http lavasoft blog 51cto com 62575 222530 对于阻塞栈 与阻塞队列相似 不同点在于栈是 后入先出 的结构 每次操作的是栈顶 而队列是 先进先出 的结构 每次操作的是队列头 这里要特别说明一
  • Java线程:线程的调度-休眠

    本文转载至 http lavasoft blog 51cto com 62575 221790 Java线程 线程的调度 休眠 Java线程调度是Java多线程的核心 只有良好的调度 才能充分发挥系统的性能 提高程序的执行效率 这里要明确的
  • java 多线程学习笔记之 线程实现(线程阻塞)

    java 实现线程方法主要分为两种方法 一种是继承 java lang Thread 另一种实现java lang Runnable接口 对于直接继承Thread 的类来说 代码大致框架是 public class MyThread ext
  • java并发包:fork/join

    本文转载至 http blog csdn net a910626 article details 51900967 Fork Join框架是Java7提供了的一个用于并行执行任务的框架 是一个把大任务分割成若干个小任务 最终汇总每个小任务结

随机推荐

  • 前端大屏常用的适配方案

    假设我们正在开发一个可视化拖拽的搭建平台 可以拖拽生成工作台或可视化大屏 或者直接就是开发一个大屏 首先必须要考虑的一个问题就是页面如何适应屏幕 因为我们在搭建或开发时一般都会基于一个固定的宽高 但是实际的屏幕可能大小不一 接下来我们就尝试
  • 安卓10开机时间优化分析

    本文从以下六点分析开机时间 1 软件环境 2 开机时间测试方法 3 开机各阶段重要的时间节点 4 bootchart工具使用说明 5 Android开机时间日志信息 6 开机时间优化方案 一 软件环境 平台 android10 0 qcom
  • Stem教育是探究式的学习方式

    在国家政策的扶持下 STEM教育慢慢进入大众的视野 走近一部分大中小学生的课堂 教育部出台的 教育信息化 十三五 规划 中明确指出有效利用信息技术推进 众创空间 建设 探索STEM教育 创客教育等新教育模式 使学生具有较强的信息意识与创新意
  • virtualbox 3.0.8 下载

    http download virtualbox org virtualbox 3 0 8
  • java命令执行jar包main方法指定相关依赖

    1 准备好工程执行所需的所有依赖jar包 也可以使用maven导出依赖的方法导出 2 将工程打包 此处打成jar包 如上图所示 zookeeper learn 1 0 SNAPSHOT jar 本次需要jdk java命令执行的jar包 3
  • #互联网生活中的隐私保护:用隐私换便利还是花钱护隐私?# 隐私保护与个人信息安全:在便利与隐私之间的取舍

    文章目录 1 看法 2 互联网生存指南 通过哪些方法来加强个人信息保护 2 1 加强个人信息安全意识 2 2 使用强密码和多因素认证 2 3 更新操作系统和软件 2 4 谨慎使用公共Wi Fi网络 2 5 定期备份个人数据 2 6 注意社交
  • Qt之自定义布局管理器(QBorderLayout)

    简述 QBorderLayout 顾名思义 边框布局 实现了排列子控件包围中央区域的布局 具体实现要求不再赘述 请参考前几节内容 简述 实现效果源码 使用 实现 QBorderLayout主要采用QLayout和QWidgetItem实现
  • MySQL 代替in/not in 的sql语句

    1 in和exists in是把外表和内表作hash连接 而exists是对外表作loop循环 每次loop循环再对内表进行查询 一直以来认为exists比in效率高的说法是不准确的 如果查询的两个表大小相当 那么用in和exists差别不
  • Textbooks Are All You Need

    本文是LLM系列文章 针对 Textbooks Are All You Need 的翻译 课本是你全部所需要的 摘要 1 引言 2 训练细节和高质量数据的重要性 3 对CodeExercise进行微调后的模型能力峰值 4 LLM评分对非常规
  • 【Python高级之定时器】

    Python高级之定时器 定时器 定时器 如果需要使用定时器去触发一些事件 Python中通过线程实现定时器timer 定时器的意思也是 一段时间后调用一个函数 用法 import threading def fun timer print
  • …\OBJ\LED.axf: Error: L6218E: Undefined symbol EXTI_Init (referred from exti.o). 错误修改

    OBJ LED axf Error L6218E Undefined symbol EXTI Init referred from exti o 错误修改 今天在移植野火的程序到元子的开发平台上时候 发现自己在中断初话中断函数的时候出现了
  • 【C语言】 函数

    函数 在计算机科学中 子程序 一个大型程序中的某部分代码 由一个或多个语句块组 成 它负责完成某项特定任务 而且相较于其他代 码 具备相对的独立性 一般会有输入参数并有返回值 提供对过程的封装和细节的隐藏 这些代码通常被集成为软 件库 C语
  • 深度学习目标跟踪算法

    ECCV 2022 OSTrack Joint Feature Learning and Relation Modeling for Tracking https blog csdn net qq 41442511 article deta
  • osgEarth的Rex引擎原理分析(七十)TileRenderModel中的RenderingPass和RenderBindings

    目标 五十五 中的问题141 TileRenderModel中的RenderingPass和RenderBindings RenderingPass渲染通道主要存放Samplers采样器列表 采样器存放的是用来渲染影像 高程的纹理和矩阵 R
  • 配置pysot- toolkit

    这个大家都没遇见啥困难 但是我就踩了比较多雷 作者的github库 不是我的 https github com StrangerZhang pysot toolkit 安装步骤 参考链接会放在后面 需要的环境 我是在Windows下配置的
  • Latex符号表——文本/数学模式通用符号

    目录 简介 速览图 详细列表 简介 这篇博客用来记录文本 数学模式通用符号 这些符号可用于文本和数学模式 速览图 详细列表 符号 命令
  • 32. 实战:PyQuery实现抓取TX图文新闻

    目录 前言 链接在评论区 链接在评论区 链接在评论区 目的 链接在评论区 链接在评论区 链接在评论区 思路 链接在评论区 链接在评论区 链接在评论区 代码实现 1 拿到页面源代码 2 解析html文件 3 拿到标题和内容 4 下载图片 5
  • 【seaweedfs】3、f4: Facebook’s Warm BLOB Storage System 分布式对象存储的冷热数据

    论文地址 Facebook的照片 视频和其他需要可靠存储和快速访问的二进制大型对象 BLOB 的语料库非常庞大 而且还在继续增长 随着BLOB占用空间的增加 将它们存储在我们传统的存储系统 Haystack 中变得越来越低效 为了提高我们的
  • Keil注释中的中文字体乱码解决方法

    1 刚刚安装好keil发现选中keil的注释部分会乱码 而且修改注释也会出现莫名的乱文 2 在edit configuration中 Editor Encoding改为Chinese GB2312即可 需要将乱码删掉 重新输入就不会出现乱码
  • java 多线程学习笔记之 线程实现(线程阻塞)

    java 实现线程方法主要分为两种方法 一种是继承 java lang Thread 另一种实现java lang Runnable接口 对于直接继承Thread 的类来说 代码大致框架是 public class MyThread ext