java多线程实战( 多个线程 修改同一个变量)

2023-11-02

java多线程实战( 多个线程 修改同一个变量)  synchronized 同步

介绍

java多线程实战

需求

创建两个线程,分别输出“a”,“b”,要求输出总和为30个。

线程介绍

一、定义线程
1、扩展java.lang.Thread类。
此类中有个run()方法,应该注意其用法:
public void run()
如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
Thread 的子类应该重写该方法。
2、实现java.lang.Runnable接口。
void run()
使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的 run 方法。
方法 run 的常规协定是,它可能执行任何所需的操作。
二、实例化线程
1、如果是扩展java.lang.Thread类的线程,则直接new即可。
2、如果是实现了java.lang.Runnable接口的类,则用Thread的构造方法:
Thread(Runnable target) 
Thread(Runnable target, String name) 
Thread(ThreadGroup group, Runnable target) 
Thread(ThreadGroup group, Runnable target, String name) 
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
 
三、启动线程
在线程的Thread对象上调用start()方法,而不是run()或者别的方法。
在调用start()方法之前:线程处于新状态中,新状态指有一个Thread对象,但还没有一个真正的线程。
在调用start()方法之后:发生了一系列复杂的事情
启动新的执行线程(具有新的调用栈);
该线程从新状态转移到可运行状态;
当该线程获得机会执行时,其目标run()方法将运行。
注意:对Java来说,run()方法没有任何特别之处。像main()方法一样,它只是新线程知道调用的方法名称(和签名)。因此,在Runnable上或者Thread上调用run方法是合法的。但并不启动新的线程。

功能实现

package com.thread;

public class ThreadTest {
	public int i=0;//计数器
	public static final int MAX=30;//总次数
	public static void main(String args[])
	{
		ThreadTest t = new ThreadTest();
		Thread thread1 = new Thread(new MeThead(t,0));
		Thread thread2 = new Thread(new MeThead(t,1));
		thread1.start();
		thread2.start();
	}
	/**
	 * 需要考虑变量i的同步问题。
	 * @return
	 */
	
	public <span style="color:#ff6666;">synchronized</span> boolean printA()
	{
		if(i<MAX)
		{
			System.out.print(i+"a");
			i++;
			return true;
		}
		return false;
		
	}
	/**
	 * 需要考虑变量i的同步问题。
	 * @return
	 */
	public <span style="color:#ff6666;">synchronized</span> boolean printB()
	{
		if(i<MAX)
		{
		System.out.print(i+"b");
		i++;
		return true;
		}
		return false;

	}
}

class MeThead implements Runnable{
	ThreadTest t;
	int method=0;
	public MeThead(ThreadTest t,int method)
	{
		this.t=t;
		this.method=method;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		while(1==1)
		{
			boolean flag =false;
			if(method==0)
			{
				flag = t.printA();
				
			}
			else if(method==1)
			{
				flag = t.printB();
			}
			//如果结束了,则退出循环
			if(flag==false)
			{
				break;
			}
		}
		
	}
	
	
}

注意点:
1.需要考虑同一个变量的同步的问题!对同一个变量的操作,必须要放入到同步方法内。否则取到的变量值会不一致!
举个例子,如果thread里面的run方法是如下实现,则就会出现变量的值不一致问题!
比如第一次,i=0,那么thread1和thread2同时进入了while循环内,thread1执行了printA方法,thread2则等待thread1释放资源。可能thread1执行了30次,最后i=30之后thread1执行完成。这时候,thread2还在等待中,发现资源已经可以使用了,则调用了printB的方法。最后就会出现打印了31次的情况!
这个需要注意的。不然很容易搞错。
如下是错误的程序:
<span style="color:#333333;"></span>package com.thread;


public class ThreadTest {
<span style="white-space:pre">	</span>public static void main(String args[])
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>ThreadTest t = new ThreadTest();
<span style="white-space:pre">		</span>Thread thread1 = new Thread(new MeThead(t,0));
<span style="white-space:pre">		</span>Thread thread2 = new Thread(new MeThead(t,1));
<span style="white-space:pre">		</span>thread1.start();
<span style="white-space:pre">		</span>thread2.start();
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>public synchronized void printA()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>System.out.print(Param.i+"a");
<span style="white-space:pre">		</span>Param.i++;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>public synchronized void printB()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>System.out.print(Param.i+"b");
<span style="white-space:pre">		</span>Param.i++;


<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>
}
/**
 * 设置成全局静态变量。
 * @author hbx
 *
 */
class Param{
<span style="white-space:pre">	</span>public static  int i=0;//两个线程每打印一次,i进行自增一次,跟MAX比较,只要小于MAX,则一直打印
<span style="white-space:pre">	</span>public static final int MAX=20;
<span style="white-space:pre">	</span>
}
class MeThead implements Runnable{
<span style="white-space:pre">	</span>ThreadTest t;
<span style="white-space:pre">	</span>int method=0;
<span style="white-space:pre">	</span>public MeThead(ThreadTest t,int method)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>this.t=t;
<span style="white-space:pre">		</span>this.method=method;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void run() {
<span style="white-space:pre">		</span>// TODO Auto-generated method stub
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span><span style="color:#ff6666;">while(Param.i<Param.MAX)</span>
<span style="white-space:pre">		</span>{
<span style="white-space:pre">			</span>
<span style="white-space:pre">			</span>if(method==0)
<span style="white-space:pre">			</span>{
<span style="white-space:pre">				</span>//System.out.println("-"+Param.i+"a-");
<span style="white-space:pre">				</span><span style="color:#ff6666;">t.printA();</span>
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>else if(method==1)
<span style="white-space:pre">			</span>{
<span style="white-space:pre">				</span>//System.out.println("-"+Param.i+"b-");


<span style="white-space:pre">				</span><span style="color:#ff6666;">t.printB()</span>;
<span style="white-space:pre">			</span>}
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>
}<span style="color:#333333;"></span>



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

java多线程实战( 多个线程 修改同一个变量) 的相关文章

随机推荐

  • Linux_CGI_CGIC - 获取Get请求字符串

    获取Get请求字符串 Get请求就是我们在浏览器地址栏输入URL时发送请求的方式 或者我们在HTML中定义一个表单 form 时 把action属性设为 Get 时的工作方式 Get请求字符串就是跟在URL后面以问号 开始的字符串 但不包括
  • 知识蒸馏的说明

    本文参考 ChatGPT 温度系数t与top p 超参怎么设置最优 知乎 知识蒸馏系列 一 三类基础蒸馏算法 OpenMMLab的博客 CSDN博客 知识蒸馏算法汇总 知乎 知识蒸馏 Old Summer的博客 CSDN博客 目录 1 Ch
  • IDEA批量替换文件换行符、分隔符CRLF、LF、CR

    全局设置 只对新文件有效 file gt setting gt code style gt Line separator 选中需要替换的分隔符类型 注意 Line separator下面有行小字 applied to new files 意
  • 各种邮箱服务软件对比

    1 宝塔邮局管理器 特点 简单易用 可视化操作 小白也能搞 还有备份功能 一般足够用了 缺点 稳定性真是差 隔三差五的不能收发 没有接口 不能任意修改邮箱密码 只能管理员修改 注意要点 一定要开启ssl 否则有些邮箱给你发邮件你收不到 建议
  • python 学习笔记07: set(集合)类型的操作

    coding UTF 8 version Python2 7 15 set gt 集合学习笔记 Help on class set in module builtin class set object set gt new empty se
  • windows-x86安装qemu-arm虚拟机及文件互传

    一 规划安装目录及环境准备 a 这里是在D盘创建 vm arm64文件夹 然后再里面部署 正在上传 重新上传取消 b 在D盘创建一个存放镜像的目录 image并把镜像放到里面 c 下载qemu 并将软件安装在D vm arm64下qemu下
  • 【解决方案】5G时代浪潮来袭,EasyNVR助力5G厂区视频监控安防采集可视化展示

    智慧工厂被认为是5G技术的重要应用场景之一 利用5G网络将生产设备无缝连接 并进一步打通设计 采购 仓储 物流等环节 满足工业环境下设备互联和远程交互应用需求 TSINGSEE青犀视频面向工厂智能化升级需求 推出5G 智慧工厂方案 构建连接
  • Java-Final关键字

    Java Final关键字 1 概念 final 最终的 final可以修饰的结构 类 最终的类 此类不能被其他类继承 比如String类 StringBuffer类 方法 最终的方法 此方法不能被重写 比如Object 类中的getCla
  • JVM小册(1)------jstat和Parallel GC日志

    JVM小册 1 jstat和Parallel GC日志 一 背景 在生产环境中 有时候会遇到OOM的情况 抛开Arthas 等比较成熟的工具以外 我们可以使用java 提供的jatat和jps jmap等工具来帮助我们排查问题和定位原因 本
  • Kubernetes笔记(6) - Service和Ingress

    Service资源概述 创建Service资源 向Service对象请求服务 Service会话粘性 服务发现 服务暴露 Ingress和Ingress Controller Ingress资源 Ingress控制器 Service资源概述
  • FID(Fusion-in-Decoder models)源码笔记

    源码 源码 https github com facebookresearch FiD 目录 源码 数据集 数据格式 预训练模型 训练 测试 src slurm py 资源调度管理 util py 配置管理 evaluation py 查找
  • 夜光带你走进 传奇语言C#(24)

    夜光序言 一只站在树上的鸟儿 从来不会害怕树枝断裂 因为它相信的不是树枝 而是它自己的翅膀 有时候 经济不独立 你发的一切飚都是浮云 正文 任务18 班级编码表维护
  • oracle 16058,Oracle 11g Data Guard ORA-16058 错误处理

    采用RMAN 备份恢复搭建Oracle 11g的Data Guard 恢复结束之后 DG 同步一直异常 主库提示如下信息 https www cndba cn Dave article 4330 SQL gt select DEST NAM
  • java设计模式之观察者模式(含完整例子和UML类图)

    java设计模式之观察者模式 1 观察者模式 1 1定义 观察者 Observer 模式的定义 指多个对象间存在一对多的依赖关系 当一个对象的状态发生改变时 所有依赖于它的对象都得到通知并被自动更新 这种模式有时又称作发布 订阅模式 模型
  • 高性能服务器架构思路(一)——缓冲策略

    本文首发腾云阁 高性能服务器架构思路 一 缓冲策略 作者介绍 韩伟 1999年大学实习期加入初创期的网易 成为第30号员工 8年间从程序员开始 历任项目经理 产品总监 2007年后创业4年 开发过视频直播社区 及多款页游产品 2011年后就
  • 孕妇有什么副业做?孕妇在家有哪些兼职可以做?

    孕妇有什么副业做 孕妇在家有哪些兼职可以做 孕妇在家选择兼职工作时 有一点一定要遵循 不能从事极端的体力工作 因为体力工作容易让孕妇出现并发症 所以孕妇一定要选择一些没有太大压力的兼职工作 有很多兼职工作时间很自由 所以特别适合怀孕的女性做
  • LAMP部署

    文章目录 LAMP简介 web服务器 web服务器的资源分为两种 静态资源和动态资源 工作流程 http响应报文 httpd与php结合的方式 httpd与php结合的方式有以下三种 lamp平台构建 环境说明
  • 不会下载软件?这5个网站别错过,纯净、安全、无捆绑

    虽然下载网站有很多 但是一不小心就会下载到各种捆绑安装包 这里就给大家分享5个比较靠谱的软件下载网站 纯净 安全 无捆绑 可以放心使用 1 Microsoft Store 一个微软旗下的电脑软件商城 它里面有很多类型的软件可以下载 首页也有
  • c/c++中,预编译指令用法汇总

    切换模式 写文章 登录 注册
  • java多线程实战( 多个线程 修改同一个变量)

    java多线程实战 多个线程 修改同一个变量 synchronized 同步 介绍 java多线程实战 需求 创建两个线程 分别输出 a b 要求输出总和为30个 线程介绍 一 定义线程 1 扩展java lang Thread类 此类中有