第二十章总结

news2024/9/29 19:21:47

继承Thread 类
        Thread 类时 java.lang 包中的一个类,从类中实例化的对象代表线程,程序员启动一个新线程需要建立 Thread 实例。

         Thread 对象需要一个任务来执行,任务是指线程在启动时执行的工作,start() 方法启动线程,该工作的功能被写在run() 方法中。
        


public class ThreadTest extends Thread{
	public void run() {
		for(int i=0;i<=10;i++) {
			System.out.print(i+" ");
		}
	}
 
	public static void main(String[] args) {
		ThreadTest t=new ThreadTest();
			t.start();
		}
}

实现 Runnable 接口
        线程都是通过扩展 Thread 类来创建的,如果程序员需要继承其他类(非Thread 类),而且还要是当前类实现多线程,那么可以通过  Runnable 接口来实现。

        实现 Runnable 接口的程序会创建一个 Thread 对象,并将 Runnable 对象与 Thread 对象相关联。

使用 Runnable 接口启动新的线程的步骤:

建立 Runnable 对象
使用参数为 Runnable 对象的构造方法创建 Thread 实例
调用 start() 方法启动线程
 

import java.awt.Container;
 
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
 
public class SwingAndThread extends JFrame{
	int count=0;//图标坐标
 
	public  SwingAndThread(){
		setBounds(300,200,250,100);//绝对定位窗体大小与位置
		Container cotainer=getContentPane();//主容器
		cotainer.setLayout(null);//使窗体不使用任何布局管理器
		
		Icon icon=new ImageIcon("1.gif");//图标对象
		JLabel jl=new JLabel(icon);//显示图标的标签
		jl.setBounds(10,10,200,50);//设置标签的位置与大小
		Thread t=new Thread() {//定义匿名线程对象
			public void run() {			
			while(true) {
				jl.setBounds(count,10,200,50);//将标签的横坐标用变量表示
				try {
					Thread.sleep(500);//使线程休眠500毫秒
				}catch(InterruptedException e) {
					e.printStackTrace();
				}
				count+=4;//使横坐标每次增加4
				if(count>=120) {
					count=10;//当图标到达标签的最右时,时其回到标签做左边
				}
			}
			
		}
	};
	t.start();//启动线程
	cotainer.add(jl);//将标签添加到容器中
	setVisible(true);//使窗体可见
	setDefaultCloseOperation(EXIT_ON_CLOSE);//设置窗体的关闭方式
	}
 
	public static void main(String[] args) {
		new SwingAndThread();
 
	}
}

 

线程的生命周期
        一旦线程进入可执行状态,它会在就绪与运行状态下转换,同时也有可能进入等待,休眠,赌塞或死亡状态。

要使线程处于就绪,有以下几种方法:

调用 sleep() 方法。
调用 wait() 方法。
等待输入/输出完成。
当线程处于就绪状态后,可以用以下几种方法使线程再次进入运行状态:

线程调用 notify() 方法。
线程调用 notifyAll() 方法。
线程调用 interrupt() 方法。
线程的休眠时间结束。
输入/输出结束。
操作线程的方法
 线程的休眠
        一种能控制线程行为的方法是调用 sleep() 方法需要一个参数用于指定该线程休眠的时间,该时间以毫秒为单位。

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
 
import javax.swing.JFrame;
 
public class SleepMethodTest extends JFrame{
	private static Color[] color= {Color.BLACK,Color.BLUE,Color.CYAN,Color.GREEN,
		Color.RED,Color.ORANGE,Color.YELLOW,Color.PINK,Color.LIGHT_GRAY};//定义颜色数组
	private static final Random rand=new Random();//创建随机对象
	
	private static Color getC() {//获取随机颜色值的方法
		return color[rand.nextInt(color.length)];
	}
	
	public  SleepMethodTest(){
		Thread t=new Thread(new Runnable() {//创建匿名线程对象
			int x=30;//定义初始坐标
			int y=50;
			
			public void run() {
				while(true) {//无限循环
					try {
						Thread.sleep(100);//线程休眠0.1秒
					}catch(InterruptedException e) {
						e.printStackTrace();
					}
					Graphics graphics=getGraphics();//获取组件绘图上下文对象
					graphics.setColor(getC());//设置绘图颜色
					graphics.drawLine(x, y,150, y++);//绘制直线并递增垂直坐标
					if(y>=180) {
						y=50;
					}
				}
			}
		});
		t.start();//启动线程
	}
 
	public static void main(String[] args) {
		init(new SleepMethodTest(),200,200);
 
	}
 
	public static void init(JFrame frame,int width,int height) {//初始化程序界面的方法
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(width, height);
		frame.setVisible(true);
	}
}

 

线程的加入

        当某个线程使用 join() 方法的加入一个线程时,另外一个线程会等待该线程执行完毕后再继续执行。

import java.awt.BorderLayout;
 
import javax.swing.JFrame;
import javax.swing.JProgressBar;
 
public class JoinTest extends JFrame{
	//定义两个线程
	private Thread threadA;
	private Thread threadB;
	//定义两个进度条组件
	private JProgressBar porgressBar=new JProgressBar();
	private JProgressBar porgressBar2=new JProgressBar();
	
 
	public static void main(String[] args) {
		JoinTest test=new JoinTest();
		test.setVisible(true);
 
	}
	public  JoinTest() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(200,200,200,100);
		getContentPane().add(porgressBar,BorderLayout.NORTH);//将进度条设置在窗体最北面
		getContentPane().add(porgressBar2,BorderLayout.SOUTH);//将进度条设置在窗体最南面
		//设置进度条显示数字字符
		porgressBar.setStringPainted(true);
		porgressBar2.setStringPainted(true);
		//使用匿名内部类形式初始化 Thread 实例
		threadA=new Thread(new Runnable() {
			int count=0;
			public void run() {//重写 run()方法
				while(true) {
					porgressBar.setValue(++count);//设置进度条的当前值
					try {
						Thread.sleep(100);//使线程A休眠100毫秒
						threadB.join();//使线程B调用join()方法
					}catch(InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
		threadA.start();//启动线程A
		threadB=new Thread(new Runnable() {
			int count=0;
			public void run() {
				while(true) {
					porgressBar2.setValue(++count);//设置进度条的当前值
					try {
						Thread.sleep(100);//使线程休眠100毫秒
					}catch(InterruptedException e) {
						e.printStackTrace();
				}
					if(count==100)//当count变量增长为100时
						break;//跳出循环
				}
			}
		});
		threadB.start();//启动线程B
	}
 
}

 

线程的中断
        以往有时候会使用 stop() 方法停止线程,但当前版本的 JDK 早已废除了 stop() 方法,不建议使用 stop() 方法来停止一个线程的运行。现在提倡在 run() 方法中使用无限循环的形式,然后使用一个布尔型标记控制循环的停止。

        如果线程是因为使用了 sleep()或 wait()方法进入了就入就绪状态,可以使用 Thread()方法,同时程序破除了 InterruptedException 异常,在异常处理时结束了 while 循环。在项目中,经常在这里执行关闭数据连接和关闭 Socket 连接等操作。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
 
public class InterruptedSwing extends JFrame{
	
	public InterruptedSwing (){
		JProgressBar porgressBar=new JProgressBar();//创建进度条
		getContentPane().add(porgressBar,BorderLayout.NORTH);//将进度条设置在窗体最北面
		JButton button=new JButton("停止");
		getContentPane().add(button,BorderLayout.SOUTH);//将进度条设置在窗体最北面
		//设置进度条显示数字字符
		porgressBar.setStringPainted(true);
		//使用匿名内部类形式初始化 Thread 实例
		Thread t=new Thread(new Runnable() {
			int count=0;
			
			public void run() {//重写 run()方法
				while(true) {
					porgressBar.setValue(++count);//设置进度条的当前值
					try {
						Thread.sleep(100);//使线程休眠100毫秒
					}catch(InterruptedException e) {//捕捉InterruptedException异常
						System.out.println("但前线程被中断");
						break;
					}
				}
			}
		});
		
		button.addActionListener(new ActionListener() {
 
			@Override
			public void actionPerformed(ActionEvent e) {
				t.interrupt();//中断线程
				
			}
			
		});
		t.start();//启动线程
	}
	
	public static void init(JFrame frame,int width,int height) {//初始化程序界面的方法
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(width, height);
		frame.setVisible(true);
	}
 
	public static void main(String[] args) {
		init(new InterruptedSwing(),100,100);
 
	}
}

线程的礼让
        Thread 类提供了一种礼让方法,使用 yied()方法表示,它只是给当前正处于运行状态的线程一个提醒,告知它可以将资源礼让给其他线程,但这仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。

        yied()方法使具有同样优先级的线程有进入可执行状态的机会,在当前线程放弃执行权时再度回到就绪状态。对于支持多任务的操作系统来说,不需要调用 yied()方法,因为操作系统会为线程自动分配 CPU 时间来执行。

线程的优先级
        每个线程都具有各自的优先级,线程的优先级可以表明在程序中该线程的重要性,如果有很多线程处于就绪状态,系统会根据优先级来决定首先使哪个线程进入运行状态。但这并不意味着低优先级的线程得不到运行,而只是它运行的概率比较小,如垃圾回收线程的优先级就按照较低。

        线程的优先级可以使用 setPriority()方法调整,如果使用该方法设置的优先级不在 1~10,将产生IllegalArgumentException 异常。
 

 
public class PriorityTest implements Runnable{
	String name;
	
	public PriorityTest(String name) {
		this.name=name;
	}
	
	@Override
	public void run() {
		String tmp="";
		for(int i=0;i<5000;i++) {
			tmp+=i;//完成5万次字符串拼接
		}
		System.out.println(name+"线程完车任务");
	}
 
	public static void main(String[] args) {
		Thread a=new Thread(new PriorityTest("A"));
		a.setPriority(1);//A线程优先级最小
		Thread b=new Thread(new PriorityTest("B"));
		b.setPriority(3);
		Thread c=new Thread(new PriorityTest("C"));
		c.setPriority(7);
		Thread d=new Thread(new PriorityTest("D"));
		d.setPriority(10);//D线程优先级最大
		a.start();
		b.start();
		c.start();
		d.start();
	}
}

 

线程同步
        在单线程程序中,每次只能做一件事情,后面的事情需要等待前面的事情完成后才可以进行,但是如果使用多线程程序,就会发生两个线程抢占资源的问题,如两个人同事说话、两个人同时过同一个独木桥。所以,在多线程编程中需要防止这些资源访问的冲突。Java 提供了线程同步的机制来防止资源访问的冲突。
线程的安全
        在编写多线程时时,因该考虑到线程安全问题。实质上线程问题来源两个线程同时存取单一对象的数据。

运行结果:

线程同步机制
        所以解决多线程资源问题的方法基本上都是采用给定时间只允许一个线程访问共享资源的方法。这时就需要给共享源上一道锁。
1、同步块***

        Java中提供了同步机制,可以有效地防止资源冲突。同步机制使用 synchronized 关键字,使用该关键字包含的代码块称为同步块,也称临界区。
 

synchronized(Object){
}

2、同步方法

        同步方法就是在方法前面用 synchronized 关键字修饰的方法。

synchronized void f(){ }

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

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

相关文章

什么是交流负载的特点和特性?

交流负载往往存在不平衡的特性&#xff0c;即三相电流和电压的幅值和相位存在差异。这是由于不同负载的性质和使用情况不同导致的&#xff0c;交流负载的功率因数是描述负载对电网的有功功率需求和无功功率需求之间关系的重要参数。功率因数可以分为正功率因数和负功率因数&…

希尔伯特和包络变换

一、希尔伯特变换 Hilbert Transform&#xff0c;数学定义&#xff1a;在数学与信号处理的领域中&#xff0c;一个实值函数的希尔伯特变换是将信号x(t)与h(t)1/(πt)做卷积&#xff0c;以得到其希尔伯特变换。因此&#xff0c;希尔伯特变换结果可以理解为输入是x(t)的线性时不…

仓库代码迁移,从一个仓库迁移到另一个仓库

A-B 1、在B创建一个新的远程仓库 2、 git clone <原Git仓库地址>git remote add origin1 <新Git仓库地址>git push -u origin1 masterorigin1自定义&#xff0c;上下保持一致

机器视觉中精度和分辨率详解!

在机器视觉中&#xff0c;分辨率作为衡量镜头和工业相机的重要参数&#xff0c;被大家熟知。精度是机器视觉中最核心的参数之一。我们一起来了解下这两个参数以及在实际组合应用中&#xff0c;如何有效匹配镜头分辨率和相机分辨率。 精度需要从多个角度来说明&#xff0c;根据…

免费部署开源大模型 ChatGLM-6B

参考&#xff1a;【大模型-第一篇】在阿里云上部署ChatGLM3-CSDN博客 ChatGLM 是一个开源的、支持中英双语的对话语言模型&#xff0c;由智谱 AI 和清华大学 KEG 实验室联合发布&#xff0c;基于 General Language Model (GLM) 架构&#xff0c;具有 62 亿参数。ChatGLM3-6B 更…

家政预约服务管理系统,轻松搭建专属家政小程序

家政预约服务管理系统&#xff0c;轻松搭建专属家政小程序app&#xff1b; 家政服务app开发架构包括&#xff1a; 1. 后台管理端&#xff1a;全面管理家政服务、门店、员工、阿姨信息、订单及优惠促销等数据&#xff0c;并进行统计分析。 2. 门店端&#xff1a;助力各门店及员工…

Windows平台下的oracle 11G-11.2.0.4补丁升级操作指南

序号 文件名称 文件说明 1 p6880880_112000_MSWIN-x86-64_OPatch 11.2.0.3.33 for DB 11.2.0.0.0 (Feb 2022) 用于升级 OPatch 2 DB_PSU_11.2.0.4.220118 (Jan 2022)_p33488457_112040_MSWIN-x86-64 主要补丁文件 注意&#xff1a;请用管理员权限运行文件内命令&#…

涂料行业ERP有哪些?涂料行业ERP怎么样

涂料这类产品的生产、包装、存储、运输等方面有特殊的管理要求&#xff0c;有些涂料企业在辅料、原料、半成品、成品、仓库、加工、设备等方面的管理存在不少问题。 如何清晰掌握库存数据&#xff0c;实时了解和掌握经营情况&#xff0c;减少库存过多带来的资金压力和材料浪费…

【代码】基于卷积神经网络(CNN)-支持向量机(SVM)的分类预测算法

程序名称&#xff1a;基于卷积神经网络&#xff08;CNN&#xff09;-支持向量机&#xff08;SVM&#xff09;的分类预测算法 实现平台&#xff1a;matlab 代码简介&#xff1a;CNN-SVM是一种常用的图像分类方法&#xff0c;结合了卷积神经网络&#xff08;CNN&#xff09;和支…

ubuntu配置免密登录vscode

1、配置免密登录 &#xff08;1&#xff09;在windows系统cmd下运行命令 ssh-keygen 一路回车&#xff0c;将会在C:\Users\用户名\.ssh目录下生成两个文件&#xff1a;id_rsa和id_rsa.pub。如下图所示。 &#xff08;2&#xff09;进入.ssh目录。如果想使用root用户&#xff0…

【刷题笔记】H指数||数组||二分查找的变体

H指数 1 题目描述 https://leetcode.cn/problems/h-index/ 给你一个整数数组 citations &#xff0c;其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。计算并返回该研究者的 h 指数。 根据维基百科上 h 指数的定义&#xff1a;h 代表“高引用次数” &#xff0c;一…

9位院士Science发表长文:人工智能的进展、挑战与未来

源自&#xff1a;量子位 “人工智能技术与咨询”发布 2023年&#xff0c;海内外9位院士及12位专家在Science《科学》合作期刊Intelligent Computing发表长篇综述论文《智能计算的最新进展、挑战和未来》。文章全面阐述了智能计算的理论基础、智能与计算的技术融…

C#开发的OpenRA游戏之属性SelectionDecorations(12)

C#开发的OpenRA游戏之属性SelectionDecorations(12) 前面分析了显示选择框的指示器类SelectionBoxAnnotationRenderable,它的作用就是画一个四个角的方角。 这个类是在属性SelectionDecorations里调用的,如下: protected override IEnumerable<IRenderable> Rende…

滴滴打车app出现系统异常,已过12小时,部分功能仍未完全恢复

据多地用户反馈&#xff0c;滴滴出行APP无法使用。11月27日深夜&#xff0c;上海、北京、广州等多地滴滴用户反馈&#xff0c;滴滴出行APP无法使用&#xff0c;地图无法加载。 不少网约车司机反映&#xff0c;“滴滴出行”系统出现故障&#xff0c;导致无法接单、定位混乱等情况…

有哪些值得推荐的数据可视化工具?

1 数据可视化工具的种类和应用场景 数据可视化工具的多样性使其能够满足不同用户的需求。一般而言&#xff0c;这些工具可分为开源版和商业版两大类。开源版特点&#xff1a;自由开源&#xff1a; 开源版数据可视化工具通常以免费形式提供&#xff0c;允许用户自由使用和修改源…

Nacos整合实际应用案例

Nacos数据隔离模型 公司->命名空间->分组->服务 命名空间通常用于隔离不同微服务之间的配置 分组用于隔离相同微服务下不同环境的配置 版本对应关系 https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E 应用案例 <par…

Apache Airflow (十四) :Airflow分布式集群搭建及测试

&#x1f3e1; 个人主页&#xff1a;IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 &#x1f6a9; 私聊博主&#xff1a;加入大数据技术讨论群聊&#xff0c;获取更多大数据资料。 &#x1f514; 博主个人B栈地址&#xff1a;豹哥教你大数据的个人空间-豹…

jquery 地址四级联级显示 不默认选择

代码效果 <body class"bgca"><img src"./files/joinTooBg.png" style"width: 100%;object-fit: cover;" alt""><!--填写申请资料--><section><div class"zi-liao"><h3 class"zong-h…

Apache Flink(一):Apache Flink是什么?

🏡 个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Clickhouse 技术-CSDN博客 🚩 私聊博主:加入大数据技术讨论群聊,获取更多大数据资料。 🔔 博主个人B栈地址:豹哥教你大数据的个人空间-豹哥教你大数据个人主页-哔哩哔哩视频 目录

搜维尔科技:8K!光线追踪!超大视场角!Varjo震撼发布XR-4系列

VR/XR硬件厂商Varjo发布了新一代XR-4系列头显—XR-4、XR-4 Focal Edition和XR-4 Secure Edition&#xff0c;升级后的头显提供了与自然视觉几乎无异的虚拟和混合现实体验。 划重点-新一代XR-4系列头显小编总结如下&#xff1a; 8K分辨率&#xff0c;高达120超大视场角&#xf…