源码如下:
package com.study.test;
/*实现Runnable对象实现多线程
* @author who
* @since 2015-05-05
* */
/*用多线程实现卖票功能
* 一共1000张票,每卖一张票-1
* */
class Ticket implements Runnable {
private int tick = 1000;
boolean bb = true;
public void run() {
// TODO Auto-generated method stub
if (bb) {
while (true) {
if (tick > 0) {
synchronized (this) {
try {
System.out.println("当前boolean值来自run方法:" + bb);
Thread.sleep(20);
System.out.println(Thread.currentThread().getName()
+ "...sale " + tick--);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
} else {
while (true)
SaleTicket();
}
}
public synchronized void SaleTicket() {
if (tick > 0) {
try {
System.out.println("当前boolean值来自SaleTicket方法:" + bb);
Thread.sleep(20);
System.out.println(Thread.currentThread().getName()
+ "...SaleTicket " + tick--);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class TicketDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Ticket t = new Ticket();
Thread t1 = new Thread(t, "线程1:");
Thread t2 = new Thread(t, "线程2:");
Thread t3 = new Thread(t, "线程3:");
Thread t4 = new Thread(t, "线程4:");
t1.start();
Sleep20();
t.bb = false;
t2.start();
Sleep20();
t.bb = true;
t3.start();
Sleep20();
t.bb = false;
t4.start();
}
public static void Sleep20() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
部分执行输出如下:
当前boolean值来自run方法:true
线程1:...sale 1000
当前boolean值来自run方法:false
线程1:...sale 999
当前boolean值来自SaleTicket方法:true
线程2:...SaleTicket 998
……………………………………
当前boolean值来自run方法:false
线程1:...sale 2
当前boolean值来自run方法:false
线程1:...sale 1
当前boolean值来自run方法:false
线程3:...sale 0
疑问如下:
1、根据代码得知,当bb变量为true时才会进入run方法的同步代码块,否则会进入SaleTicket同步方法中,但是以上输出当前boolean值完全是乱的。
2、针对两个同步代码块都做了同步安全处理,尽然还有“0”值出现,在开启两个线程的情况下不会出现。
run()中,先判断bb值,再进入同步代码段,导致可能出现这种情况:bb值为true, 进入同步代码段前,另一线程修改bb的值为false。同理,synchronized也没有把tick作为临界区保护起来。