日期:2014-05-18  浏览次数:20648 次

Java线程安全问题(sychronized)
经典的火车票问题:
public class ThreadDemo2 {
public static void main(String[] args) {
Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
Ticket t3 = new Ticket();
Ticket t4 = new Ticket();
t1.start();
t2.start();
t3.start();
t4.start();
}
}

class Ticket extends Thread {
private  int ticket;
Object obj = new Object();
public void run() {
while(true) {
synchronized (obj) {
if (ticket < 10) {
System.out.println(Thread.currentThread().getName()
+ "--->" + ticket);
ticket++;
}
}
}
}
}

如果我把Ticket类中的ticket变量定义成static,就是这样private static  int ticket;也不会有错啊。
为什么一定要用同步呢?
------解决方案--------------------
引用:
Quote: 引用:

测试一下,事实胜于雄辩

试了,而且从理论上讲的话,静态变量在内存中是唯一的啊,也没错啊。开始的程序写错了````

正因为是唯一的,多个线程在对其进行读写操作的时候,就会出现时间差:比如某时刻value=10,两个线程同时对其操作,想各自占用一张票,如果没有锁,同时读value得到10,然后各自占用一个,减1操作,各自都认为该写9进去。

synchronized的作用就是“互斥使用”:一个线程获得资源的锁,读写过程中,另外一个线程会等待该资源锁释放了,才进行后续操作。


有时候机器性能太好了,int型参数操作很快,体现不出来,建议LZ在案例中,读取、加减操作时,Thread.sleep()那么一小会儿,可能就体现出来并发问题了。