blusewang 2013-06-02 11:27
浏览 346
已采纳

java 并发 synchronized问题

上码:

 

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()方法应该有机会得到执行啊?

  • 写回答

3条回答

  • teasp 2013-06-03 08:26
    关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛