0 0

java 并发 synchronized问题5

上码:

 

package com.hxsmart.thread.synchronize;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class CleanRoom {
	private Integer student=0;
	private Integer machine=0;
	
	public String getDateStr(){
		return "  Thread"+Thread.currentThread().getName()+"  *time: "+new SimpleDateFormat("mm:ss").format(new Date());
	}
	public void stuClean(){
		System.out.println("enter stuClean");
		synchronized (student) {
			for(int i=0;i<5;i++){
				System.out.println("stu"+getDateStr());
				student++;
				try {
					TimeUnit.SECONDS.sleep(3);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	public void macClean(){
		System.out.println("enter macClean");
		synchronized (machine) {
			for(int i=0;i<5;i++){
				System.out.println("mac"+getDateStr());
				machine++;
//				try {
//					TimeUnit.SECONDS.sleep(3);
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
			}
		}
	}
	public static void main(String[] args) {
		CleanRoom c=new CleanRoom();
		
		StuThread t1=new StuThread(c);
		MacThread t2=new MacThread(c);
		
		t1.start();
		t2.start();
	}
	public Integer getStudent() {
		return student;
	}
	public void setStudent(Integer student) {
		this.student = student;
	}
	public Integer getMachine() {
		return machine;
	}
	public void setMachine(Integer machine) {
		this.machine = machine;
	}
	
}

class StuThread extends Thread{
	CleanRoom clean;
	public StuThread() {
		super();
	}
	public StuThread(CleanRoom clean) {
		super();
		this.clean = clean;
	}
	@Override
	public void run() {
		//for(int i=0;i<5;i++)
		clean.stuClean();
		System.out.println("stu: "+clean.getStudent()+"**  mac:**"+clean.getMachine());
	}
	public CleanRoom getClean() {
		return clean;
	}
	public void setClean(CleanRoom clean) {
		this.clean = clean;
	}
	
}
class MacThread extends Thread{
	CleanRoom clean;
	public MacThread() {
		super();
	}
	public MacThread(CleanRoom clean) {
		super();
		this.clean = clean;
	}
	@Override
	public void run() {
		//for(int i=0;i<5;i++)
		clean.macClean();
		System.out.println("stu: "+clean.getStudent()+"**  mac:**"+clean.getMachine());
	}
	public CleanRoom getClean() {
		return clean;
	}
	public void setClean(CleanRoom clean) {
		this.clean = clean;
	}
}

 输出:

 

 

enter stuClean
enter macClean
stu  ThreadThread-0  *time: 12:38
stu  ThreadThread-0  *time: 12:41
stu  ThreadThread-0  *time: 12:44
stu  ThreadThread-0  *time: 12:47
stu  ThreadThread-0  *time: 12:50
stu: 5**  mac:**0
mac  ThreadThread-1  *time: 12:53
mac  ThreadThread-1  *time: 12:53
mac  ThreadThread-1  *time: 12:53
mac  ThreadThread-1  *time: 12:53
mac  ThreadThread-1  *time: 12:53
stu: 5**  mac:**5

 问题:

 

t1和t2线程,分别调用的是CleanRoom类同一实例c的不同方法,并且这两个方法没有把这个实例C锁上,两个方法所锁定的资源分别是c实例的两个不同的属性,按道理来说,这两个线程应该是并发执行的。

但是事实不如此,t2线程在t1线程没有执行完成前,始终处于等待状态。

 

求解!

stuClean方法中调用TimeUnit.SECONDS.sleep(3)后,macClean()方法应该有机会得到执行啊?

2013年6月02日 11:27

3个答案 按时间排序 按投票排序

1 0

采纳的答案

哈哈,神秘现象不神秘。Integer类会缓存一部分对象,从-128到127的数在系统中都只有一个Integer对象(假如你用自动装箱和valueof方法得到对象,其实这两者是一回事)。因此你锁住的两个对象其实都是同一个Integer(0),当自增之后,那两个对象的引用指向了别的对象,比如Integer(1)。最终执行的结果就是student和machine都指向了Integer(5)。你把两个=0改成=new Integer(0)就OK啦。

2013年6月03日 08:26
0 0

sleep执行的时候是没有释放锁的,他还手里面握着锁头的,其他线程竞争不走CPU资源的,他还占据着呢,
比如wait的话,在wait(3000),的时候这个时候系统的其他线是可以竞争CPU资源的。

本人的一点点见解

2013年6月02日 22:59
0 0

你把private Integer student=0改成private Integer student=new Integer(0);同样private Integer machine=0;改成private Integer machine=new Integer(0);再试试看,应该就不会锁住了。

真的太神奇了。
难道是因为private Integer student=0和private Integer machine=0;实际上指向的是一个对象,所以锁被加在一个对象上,所以出现了等待的情况?
但是如果指向同一对象的话,machine不应该还是从0开始计数啊。

求哪位大神解释!

2013年6月02日 16:20

相关推荐

    java并发编程实战源码,java并发编程实战pdf,Java

    《Java并发编程实战》是Java并发编程领域的一本经典著作,它深入浅出地介绍了如何在Java平台上进行高效的多线程编程。这本书的源码提供了丰富的示例,可以帮助读者更好地理解书中的理论知识并将其应用到实际项目中。...

    java并发编程2

    Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。以下是对标题和描述中所提及的几个知识点的详细解释: 1. **线程与并发** - **线程*...

    《java 并发编程实战高清PDF版》

    《Java并发编程实战》是一本深入探讨Java平台并发编程的权威指南。这本书旨在帮助开发者理解和掌握在Java环境中创建高效、可扩展且可靠的多线程应用程序的关键技术和实践。它涵盖了从基本概念到高级主题的广泛内容,...

    java并发编程内部分享PPT

    总的来说,这份“java并发编程内部分享PPT”涵盖了Java并发编程的多个重要方面,包括线程创建与管理、同步机制、并发容器、线程池、并发问题以及异步计算。通过深入学习和实践这些知识点,开发者可以更好地应对多...

    java并发编程艺术

    描述中反复提到“java并发编程艺术”,这暗示书中将详细介绍如何优雅地设计和管理线程,避免常见的并发问题,如死锁、竞态条件和活锁。 在Java中,同步是控制多个线程访问共享资源的方式,主要通过`synchronized`...

    Java 并发编程实战.pdf

    通过上述内容的学习,开发者不仅能掌握Java并发编程的基本原理和技术要点,还能学会如何将这些理论应用于实际工作中,解决复杂的多线程问题。无论是对于初学者还是有一定经验的开发者来说,《Java并发编程实战》都是...

    java并发编程实战(英文版)

    对于那些需要解决复杂并发问题的高级开发者,《Java并发编程实战》提供了许多实用的技术和设计模式,例如: - **不可变对象**:介绍如何设计不可变对象以提高代码的安全性和效率。 - **锁分离**:讲解锁分离技术,...

    JAVA并发编程实践.pdf+高清版+目录 书籍源码

    《JAVA并发编程实践》这本书是Java开发者深入理解并发编程的重要参考资料。它涵盖了Java并发的核心概念、工具和最佳实践,旨在帮助读者在多线程环境下编写高效、安全的代码。 并发编程是现代软件开发中的关键技能,...

    JAVA并发编程艺术pdf版

    通过深入学习《JAVA并发编程艺术》,开发者能更好地理解并发编程的原理,熟练运用Java提供的并发工具和API,解决实际开发中的多线程问题,提高软件的性能和稳定性。这是一本值得每一位Java开发者研读的书。

    Java并发编程实践高清pdf及源码

    《Java并发编程实践》是一本深入探讨Java多线程编程的经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowles和David Holmes等专家共同编写。这本书全面介绍了Java平台上的并发编程技术,是Java开发...

    java 并发编程的艺术pdf清晰完整版 源码

    《Java并发编程的艺术》这本书是Java开发者深入理解并发编程的重要参考书籍。这本书全面地介绍了Java平台上的并发和多线程编程技术,旨在帮助开发者解决在实际工作中遇到的并发问题,提高程序的性能和可伸缩性。 ...

    (PDF带目录)《Java 并发编程实战》,java并发实战,并发

    《Java 并发编程实战》是一本专注于Java并发编程的权威指南,对于任何希望深入了解Java多线程和并发控制机制的开发者来说,都是不可或缺的参考资料。这本书深入浅出地介绍了如何在Java环境中有效地管理和控制并发...

    java并发编程实践pdf笔记

    Java并发编程实践是Java开发中不可或缺的一个领域,它涉及到如何高效、正确地处理多线程环境中的任务。这本书的读书笔记涵盖了多个关键知识点,旨在帮助读者深入理解Java并发编程的核心概念。 1. **线程和进程的...

    Java并发 synchronized锁住的内容解析

    Java并发synchronized锁住的内容解析是Java并发编程中的一种重要机制,用于解决多线程并发访问同一个资源时可能出现的线程安全问题。通过使用synchronized关键字,可以锁住当前对象的当前方法,使得其他线程访问该...

    java并发编程书籍

    Java并发编程是软件开发中的一个关键领域,尤其是在大型企业级应用和分布式系统中。通过学习相关的书籍,开发者可以深入理解如何有效地设计和实现高效的多线程应用程序,避免并发问题,如竞态条件、死锁、活锁等。...

    java同步synchronized关键字用法示例

    Java中的`synchronized`关键字是多线程编程中的一个重要概念,用于控制并发访问共享资源时的同步机制。在Java中,当多个线程试图同时访问和修改同一块代码或数据时,可能会导致数据不一致的问题。为了解决这个问题,...

    Java 并发核心编程

    #### 一、Java并发概述 自Java诞生之初,其设计者就赋予了该语言强大的并发处理能力。Java语言内置了对线程和锁的支持,这使得开发者能够轻松地编写多线程应用程序。本文旨在帮助Java开发者深入理解并发的核心概念...

    Java并发编程实践.pdf

    ### Java并发编程实践 #### 一、并发编程基础 ##### 1.1 并发与并行的区别 在Java并发编程中,首先需要理解“并发”(Concurrency)和“并行”(Parallelism)的区别。“并发”指的是多个任务在同一时间段内交替...

    Java并发-Synchronized关键字.docx

    因此,Java并发库中提供了其他高级并发控制工具,如`java.util.concurrent`包下的`ReentrantLock`、`Semaphore`等,它们在某些场景下可以提供更好的性能和更细粒度的锁控制。 总的来说,`synchronized`关键字是Java...

Global site tag (gtag.js) - Google Analytics