神牛进,多线程问题!!!

zkn_CS_DN_2013 2014-05-15 05:12:55
package com.zken.pkg;

public class MultiThread implements Runnable {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public void run() {
if (this.getName().equals("1")) {
m1();
}else if(this.getName().equals("2")){
m2();
}
}

private synchronized void m1() {
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("m1::::"+this.getName());
}

private void m2() {
System.out.println("m2::::"+this.getName());
}

public static void main(String[] args) {
MultiThread multiThread = new MultiThread();
Thread thread1 = new Thread(multiThread);
multiThread.setName("1");
thread1.start();
Thread thread2 = new Thread(multiThread);
multiThread.setName("2");
thread2.start();
}
}

输出结果是:
m2::::2
m2::::2
为什么两次执行的都是m2方法?不应该呀????

...全文
644 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 17 楼 pengxiao618 的回复:
撼地神牛跳大五杀
不懂~~~~~~~~~~~~~
  • 打赏
  • 举报
回复
引用 18 楼 ljl434841 的回复:
如此多人,神牛?跳大啊!
朋友有什么高见,不妨交流交流啊~~~~~~~~~~~~~~~~~
  • 打赏
  • 举报
回复
引用 16 楼 fbpcchen 的回复:
public class Bank implements Runnable{
	private int money = 20000;
	
	public int getMoney() {
		return money;
	}
	public void setMoney(int money) {
		this.money = money;
	}
	private String matipulate;
	
	public String getMatipulate() {
		return matipulate;
	}
	public void setMatipulate(String matipulate) {
		this.matipulate = matipulate;
	}
	public void run() {
		if(matipulate.equals("get"))
			getMoney(1000);
		if(matipulate.equals("save"))
			saveMoney(1000);
		
	}
	private int getMoney(int num){
		this.money -= num;
		System.out.println("from bank get money:" + num);
		System.out.println(getMoney());
		return num;
	}
	private void saveMoney(int num){
		this.money += num;
		System.out.println("to bank save money:" + num);
		System.out.println(getMoney());
	}
	public static void main(String[] args) {
		Bank bank = new Bank();
		Thread t1 = new Thread(bank);
		Thread t2 = new Thread(bank);
		bank.setMatipulate("get");
		t1.start();
		bank.setMatipulate("save");
		t2.start();
		System.out.println(bank.getMoney());
		
	}

}
楼主运行一下这个程序,多运行几次,你就知道线程之间的执行顺序了。有点类似于多道程序处理机在没有引入进程之前,并发程序的运行会产生间断性、不可再现性和失去封闭性的特点
跑了几次,得出了一个结论,不知正确与否:主线程跑的比子线程要快很多,也就是说主线程的优先级要高于子线程的,不知我这样理解可有问题?????????
绝对在乎妮 2014-05-16
  • 打赏
  • 举报
回复
如此多人,神牛?跳大啊!
  • 打赏
  • 举报
回复
撼地神牛跳大五杀
fbpcchen 2014-05-16
  • 打赏
  • 举报
回复
public class Bank implements Runnable{
	private int money = 20000;
	
	public int getMoney() {
		return money;
	}
	public void setMoney(int money) {
		this.money = money;
	}
	private String matipulate;
	
	public String getMatipulate() {
		return matipulate;
	}
	public void setMatipulate(String matipulate) {
		this.matipulate = matipulate;
	}
	public void run() {
		if(matipulate.equals("get"))
			getMoney(1000);
		if(matipulate.equals("save"))
			saveMoney(1000);
		
	}
	private int getMoney(int num){
		this.money -= num;
		System.out.println("from bank get money:" + num);
		System.out.println(getMoney());
		return num;
	}
	private void saveMoney(int num){
		this.money += num;
		System.out.println("to bank save money:" + num);
		System.out.println(getMoney());
	}
	public static void main(String[] args) {
		Bank bank = new Bank();
		Thread t1 = new Thread(bank);
		Thread t2 = new Thread(bank);
		bank.setMatipulate("get");
		t1.start();
		bank.setMatipulate("save");
		t2.start();
		System.out.println(bank.getMoney());
		
	}

}
楼主运行一下这个程序,多运行几次,你就知道线程之间的执行顺序了。有点类似于多道程序处理机在没有引入进程之前,并发程序的运行会产生间断性、不可再现性和失去封闭性的特点
fbpcchen 2014-05-16
  • 打赏
  • 举报
回复
如果两个线程之间没有使用睡眠阻塞,那么在使用的同一个Runnable对象里面的nama变量赋值都为“2”,所以都是执行的m2方法
  • 打赏
  • 举报
回复
引用 13 楼 zkn_CS_DN_2013 的回复:
[quote=引用 8 楼 yyfhz 的回复:] 问题在于LZ的代码用了同一个MultiThread对象来生成2个线程,导致对象MultiThread里面的变量出现同步问题。 LZ可以试着将代码改成

    public static void main(String[] args) {
        MultiThread multiThread = new MultiThread();
        Thread thread1 = new Thread(multiThread);
        multiThread.setName("1");
        thread1.start();
        MultiThread multiThread2 = new MultiThread();
        Thread thread2 = new Thread(multiThread2);
        multiThread2.setName("2");
        thread2.start();
    }
就会正常了。
[/quote] 我不是要求结果正常就行了,关键是想要明白主线程和子线程之间的关系和执行机制~~~~~~~~~
  • 打赏
  • 举报
回复
引用 8 楼 yyfhz 的回复:
问题在于LZ的代码用了同一个MultiThread对象来生成2个线程,导致对象MultiThread里面的变量出现同步问题。 LZ可以试着将代码改成

    public static void main(String[] args) {
        MultiThread multiThread = new MultiThread();
        Thread thread1 = new Thread(multiThread);
        multiThread.setName("1");
        thread1.start();
        MultiThread multiThread2 = new MultiThread();
        Thread thread2 = new Thread(multiThread2);
        multiThread2.setName("2");
        thread2.start();
    }
就会正常了。
  • 打赏
  • 举报
回复
引用 11 楼 xuebichongkafei 的回复:
[quote=引用 楼主 zkn_CS_DN_2013 的回复:]
package com.zken.pkg;

public class MultiThread implements Runnable {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void run() {
		if (this.getName().equals("1")) {
			m1();
		}else if(this.getName().equals("2")){
			m2();
		}
	}

	private synchronized void m1() {
		try {
			Thread.sleep(1000 * 10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("m1::::"+this.getName());
	}

	private void m2() {
		System.out.println("m2::::"+this.getName());
	}

	public static void main(String[] args) {
		MultiThread multiThread = new MultiThread();
		Thread thread1 = new Thread(multiThread);
		multiThread.setName("1");
		thread1.start();
		Thread thread2 = new Thread(multiThread);
		multiThread.setName("2");
		thread2.start();
	}
}
输出结果是: m2::::2 m2::::2 为什么两次执行的都是m2方法?不应该呀????
楼上加睡眠可以出现不同情况. 楼主这种情况的出现应该是,主线程执行代码速度很快执行过去(与个人电脑配置有关系),开启了两个线程,那么主线程一瞬间执行完代码,这时候name已经覆盖了上一次的赋值,成为了2,,直到主线程结束后,另外两个线程才抢到执行权.所以两个线程分别抢到执行全的时候,name都等于2,当然两字都是执行m2,name为2了. 不知道这种表达,楼主能否明白[/quote] 嗯嗯,同意!!!!!
  • 打赏
  • 举报
回复
引用 39 楼 mybeta 的回复:
[quote=引用 33 楼 zkn_CS_DN_2013 的回复:] [quote=引用 29 楼 mybeta 的回复:] 因为是同一个Runnable,第一个线程虽然调用了start(),但可能还没开始执行,接下来第二个线程又把这个Runable的name改变了,然后两个线程开始执行run方法,这样是不是会出现你的情况呢
嗯,好,简单明了,就是线程同步问题,你对主线程和子线程之间的关心有什么独到的见解吗?不妨给大家分享一下哈~~~~~~~~~~~~[/quote] 我觉得你这个不是子线程和主线程的问题,只是单纯的两个线程之间的问题。你这里相当于用两个线程操作同一个对象,所以出现的问题。我不知道你要测什么啊,那个如果是要测试是哪个线程在执行哪个方法,可以设置Thread的name。[/quote] 怎么可能是两个单纯两个线程之间的关系?!!!那两个子线程都是由主线程main创建的,跟线程之间争抢cpu资源有关,我主要想测试一下线程并发时执行顺序和线程之间的关系问题,以及深入理解一下cpu是分配时间片给线程的。。不过,看了许多网上的文章以及大家积极的回答和帮助,我现在已经理解的差不多了,感谢》》》》
mybeta 2014-05-16
  • 打赏
  • 举报
回复
引用 33 楼 zkn_CS_DN_2013 的回复:
[quote=引用 29 楼 mybeta 的回复:] 因为是同一个Runnable,第一个线程虽然调用了start(),但可能还没开始执行,接下来第二个线程又把这个Runable的name改变了,然后两个线程开始执行run方法,这样是不是会出现你的情况呢
嗯,好,简单明了,就是线程同步问题,你对主线程和子线程之间的关心有什么独到的见解吗?不妨给大家分享一下哈~~~~~~~~~~~~[/quote] 我觉得你这个不是子线程和主线程的问题,只是单纯的两个线程之间的问题。你这里相当于用两个线程操作同一个对象,所以出现的问题。我不知道你要测什么啊,那个如果是要测试是哪个线程在执行哪个方法,可以设置Thread的name。
  • 打赏
  • 举报
回复
我再声明一下啊,提问的问题简单还是复杂不重要,重要的是隐藏在其中深层次的原理,希望可以通过简单的例子引起大家的热烈讨论,进而延伸到更深层次的领域,各自说出自己的理解和看法,请大家不要拍砖啊!~~~~~~~~~~~
  • 打赏
  • 举报
回复
引用 35 楼 u013646870 的回复:
真的有牛牛牛牛牛人唉。
必须的,高手都在民间,民间的高手都在网上!!!网上的高手都在csdn
  • 打赏
  • 举报
回复
引用 32 楼 qq331077064 的回复:
你这个问题需要神牛吗? multiThread.setName("2");执行的时候,前面一个线程没有执行到 if (this.getName().equals("1")) { 如果要研究多线程和并发,可以研究 wait(),notify(),ThreadPoolExecutor,BlockingQueue,Semaphore,Barrier,Latch,ReentrantLock
嗯,不好意思啊,本人水平太次。。。请问你是如何理解java中的同步和数据库中锁的机制的??????????????????
u013646870 2014-05-16
  • 打赏
  • 举报
回复
真的有牛牛牛牛牛人唉。
  • 打赏
  • 举报
回复
还有一个问题哈,各位神牛是如何理解java中的sychronized同步和数据库中锁的概念的,我觉得它们之间是很相似的,但我不能系统完整的表达出它们之间的关系,各位神牛有什么高见,请不吝赐教啊~~~~~~~~~~~~~~~~~~~
  • 打赏
  • 举报
回复
引用 29 楼 mybeta 的回复:
因为是同一个Runnable,第一个线程虽然调用了start(),但可能还没开始执行,接下来第二个线程又把这个Runable的name改变了,然后两个线程开始执行run方法,这样是不是会出现你的情况呢
嗯,好,简单明了,就是线程同步问题,你对主线程和子线程之间的关心有什么独到的见解吗?不妨给大家分享一下哈~~~~~~~~~~~~
郑涛 2014-05-16
  • 打赏
  • 举报
回复
你这个问题需要神牛吗? multiThread.setName("2");执行的时候,前面一个线程没有执行到 if (this.getName().equals("1")) { 如果要研究多线程和并发,可以研究 wait(),notify(),ThreadPoolExecutor,BlockingQueue,Semaphore,Barrier,Latch,ReentrantLock
  • 打赏
  • 举报
回复
感谢大家热情的回答,如有兴趣的话,可以参考下这篇文章: http://blog.csdn.net/it_man/article/details/7196645
加载更多回复(20)
源码直接下载地址: https://pan.quark.cn/s/a4b39357ea24 ### Home Bus 协议概述 Home Bus协议,亦被称为家庭总线协议,是由日本研发的一种专门应用于家庭自动化领域的通信标准。该协议在商用空调及其他家用电器的远程操控方面具备广泛的应用范围。借助Home Bus协议,设备之间能够达成高效的通信,使用户能够更加便利地监管家庭中的各类智能设备。 ### ECHONET协议及其背景 Home Bus协议与ECHONET协议存在紧密的联系,实际上,ECHONET代表了一种更为具体的技术规范,其目的在于为家庭自动化领域构建一个开放且统一的通信标准。ECHONET由ECHONET财团负责维护与支持,该组织致力于推动该协议的进步与标准化进程。ECHONET协议的应用范围不仅限于家庭环境,还包括了楼宇自动化以及工业自动化等多个领域。 #### ECHONET的历史版本及修订记录 - **Version 1.0**:发布于2000年3月18日,同年7月对联盟成员公开,最终于同年对公众发布。 - **Version 1.01**:在2001年5月23日,向联盟成员发布,主要进行了补充和勘误工作。 - **Version 2.00**:2001年8月7日,针对联盟成员发布。此版本中将电源线A和电源线B两种方式合并为单一电源线方式(基于电源线A),并对相关描述进行了调整。 - **Version 2.01**:2001年11月9日,进行了一些必要的修正,包括排版错误的修正、术语的标准化等。 - **Version 2.10**:经历预览版和草案阶段后,于2002年3月7日正式对联盟成员开放。此次更新主要涉及第3部分关于状态转换的描述修改。 -...
源码直接下载地址: https://pan.quark.cn/s/a4b39357ea24 依据所提供的文档材料,可以归纳出以下核心知识点: 1. **TM1668控制器**:TM1668属于一种专为驱动LED显示屏设计的专用驱动集成电路,其特别适用于驱动数码管,能够达成多路LED的驱动与控制,从而提升了显示的效率。 2. **程序简化与时序控制**:程序完成了对TM1668芯片的操作,其功能已经达到最简化程度,且时序设置正确无误。在编程过程中,确保时序的准确性至关重要,因为它直接关联到设备能否正常运作。 3. **寄存器操作**:在编程实践中,运用了 uchar、int 等数据类型来表示数据及控制位。uchar或许是一种8位无符号字符类型,用于存储数据信息。同时,还涉及到对特定位的操作,比如 & 、 >> 等,这些操作用于设定或检测数据位的状态。 4. **硬件控制位**:在代码中,设定了用于控制TM1668的硬件控制位,涵盖 STB(片选信号)、CLK(时钟信号)以及 DIO(数据输入输出信号)。这些控制位的作用在于向TM1668发送指令与数据信息。 5. **数码管显示控制**:借助一系列的 send_data 函数调用,向TM1668发送控制指令与数据,以此来调控数码管的显示状态。例如,设定显示位、挑选显示地址、将数据传输至特定的数码管显示单元等。 6. **定时器中断**:在程序设计中,应用了定时器中断(INT0_timer)来周期性地执行任务。通过设定定时器的初始值(TH0和TL0),定时器在倒计时完成后会触发中断,使得程序能够以固定的频率更新数码管的显示内容。 7. **中断服务程序**:设定了一个中断服务程序,在定时器中断发生时被调用。在中断服务程序...
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 在信息技术领域中,DM码(Data Matrix Code)被视为一种二维条形码规范,其功能在于储存海量信息,并在工业自动化、电子元件标记等众多场景中得到普遍应用。DM码的辨识过程是图像处理及计算机视觉学科内的核心研究方向,它涵盖了图像采集、初步处理、特征提取以及模板比对等多个环节。在VC++平台之上,借助MFC(Microsoft Foundation Classes)库开展DM码辨识能够构建一个高效的应用开发环境。 我们将探讨"自适应阈值分割"这一流程。在DM码辨识的进程中,图像的初步处理扮演着至关重要的角色,而阈值分割则是将图像实现二值化的常用手段。自适应阈值分割能够依据图像的局部属性灵活设定阈值,有效处理光照不均、对比度较低等情况。这通常涉及到计算每个像素点邻近区域内的平均灰度级别,并设定一个阈值,通过像素点自身的灰度值与其邻近区域灰度值的关联来判定其最终呈现的黑白状态。这样的方法能够确保DM码在复杂的图像背景下依然能够被精确地辨识出来。 随后,"快速定位"技术也是DM码辨识过程中的关键环节。在图像经过二值化处理后,需要迅速识别出DM码所在的位置。一种常用的方法是进行边缘检测,例如采用Canny算子或Sobel算子,这些方法能够识别出图像中的轮廓线。然后,借助矩形模板匹配,例如通过霍夫变换探测直线,并结合交点信息来确定DM码的四个顶点,从而精确获取DM码的位置信息。 在MFC框架的支持下,我们可以运用其图形设备接口(GDI+)以及OpenCV等库来实现上述功能。GDI+提供了丰富的绘图工具,能够便捷地处理图像的显示和初步处理;而OpenCV则包含了大量的图像处理算法,...
标题SpringBoot博物馆综合服务管理系统的设计与实现AI更换标题第1章引言介绍博物馆综合服务管理系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景与意义阐述博物馆信息化管理的必要性和系统开发的重要性。1.2国内外研究现状分析国内外博物馆管理系统的研究现状与存在的不足。1.3研究方法以及创新点概述本文的研究方法,并指出系统的创新之处。第2章相关理论介绍系统开发所需的相关技术理论。2.1SpringBoot框架介绍阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.2数据库技术介绍系统所采用的数据库技术,如MySQL等。2.3Web开发技术概述Web开发技术,包括前端和后端技术。2.4系统安全技术介绍系统安全相关的技术,如数据加密、用户认证等。第3章系统需求分析与设计详细分析系统的需求,并给出系统的设计方案。3.1系统需求分析从功能需求、性能需求等方面对系统进行详细分析。3.2系统架构设计给出系统的总体架构设计,包括各个模块的功能划分。3.3数据库设计设计系统的数据库结构,包括表结构、字段设计等。3.4界面设计展示系统的用户界面设计,包括页面布局、交互设计等。第4章系统实现详细介绍系统的实现过程,包括各个模块的实现方法。4.1系统开发环境搭建介绍系统开发所需的软件、硬件环境及其配置方法。4.2核心功能模块实现详细介绍系统核心功能模块的实现代码和逻辑。4.3系统集成与测试阐述系统各个模块的集成方法以及系统测试的过程和结果。第5章系统应用与效果评估介绍系统的应用情况,并对系统的效果进行评估。5.1系统应用情况系统在博物馆中的实际应用情况。5.2系统效果评估从性能、用户满意度等方面对系统效果进行评估。5.3对比方法分析通过与其他系统对比,分析本系统的优势和不足。第6章结论与展望总结本文的研究成果,并展望未来的研究方向。6.1研究结论概括本文的主要研

62,622

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧