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 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波
  • ¥15 针对曲面部件的制孔路径规划,大家有什么思路吗
  • ¥15 钢筋实图交点识别,机器视觉代码
  • ¥15 如何在Linux系统中,但是在window系统上idea里面可以正常运行?(相关搜索:jar包)
  • ¥50 400g qsfp 光模块iphy方案
  • ¥15 两块ADC0804用proteus仿真时,出现异常
  • ¥15 关于风控系统,如何去选择
  • ¥15 这款软件是什么?需要能满足我的需求
  • ¥15 SpringSecurityOauth2登陆前后request不一致