当前位置: 代码迷 >> J2EE >> 大神,Thread 、synchronized出有关问题了
  详细解决方案

大神,Thread 、synchronized出有关问题了

热度:78   发布时间:2016-04-17 22:59:22.0
求助大神,高手进,Thread 、synchronized出问题了
package com.muke.reflect;

public class Demo5 extends Thread{
public static int  ticket=100;
public void run(){
this.sale();
}
public synchronized void sale(){
while(ticket>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"出售"+ticket--);
}
}
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
Demo5 d1=new Demo5();
Demo5 d2=new Demo5();
Demo5 d3=new Demo5();
Demo5 d4=new Demo5();
d1.start();
d2.start();
d3.start();
d4.start();
}

}

不知道为什么,加了static,而且还有同步代码块,不能实现资源的同步。
------解决思路----------------------
因为线程所用的锁是对象本身。而你创建了4个Demo5对象。所用的锁是各自用各自的。所以达不到同步的期望。你只要将sale()方法修改为static方法。则该方法用的锁会变为使用Demo5.class类对象。如下代码:

public static synchronized void sale(){
        while(ticket>0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"出售"+ticket--);
        }
    }

实现”同步“后,楼主会发现你的代码逻辑存在一问题,就是永远只有1个线程能执行ticket操作。某线程进入run方法执行后。加上锁,而run方法的内容中用的while循环一直做ticket--操作。直接减为0了,才退出方法,释放锁。而后其他线程进来后已经没法操作(ticket为0了)。所以楼主的代码可以调整下:

public void sale(){
        while (ticket > 0) {
            synchronized (Demo5.class) {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName()+"出售"+ ticket--);
                }
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
  相关解决方案