Java中许多资源都是共享存在的,比如,火车票售卖,全国各地有许多卖火车票的窗口,但是火车票是一定的,它是一个共享的资源。假如,在同一时间点,两个售票窗口刚好同时卖一张票,就会出现同票的麻烦。For example:
<span style="font-size:18px;">package Test;
public class TicketWindow extends Thread{
TicketCount tc;
private int name;
public TicketWindow(TicketCount tc,int name)
{
this.tc = tc;
this.name = name;
}
public void run()
{
while(true)
{
if(tc.count>0)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name+"号窗口已出票: "+tc.count--+"号票");
}
}
}
}
</span>
<span style="font-size:18px;">public class TicketCount {
int count = 10;
}</span>
<span style="font-size:18px;">package Test;
public class Main {
public static void main(String[] args) {
TicketCount tc = new TicketCount();
//一号窗口
TicketWindow tw1 = new TicketWindow(tc, 1);
tw1.start();
//二号窗口
TicketWindow tw2 = new TicketWindow(tc, 2);
tw2.start();
//三号窗口
TicketWindow tw3 = new TicketWindow(tc, 3);
tw3.start();
}
}</span>
上面代码的结果为:
1号窗口已出票: 10号票
3号窗口已出票: 10号票
2号窗口已出票: 9号票
1号窗口已出票: 8号票
2号窗口已出票: 7号票
3号窗口已出票: 6号票
1号窗口已出票: 5号票
2号窗口已出票: 4号票
3号窗口已出票: 3号票
1号窗口已出票: 2号票
2号窗口已出票: 1号票
3号窗口已出票: 0号票
1号窗口已出票: -1号票
可以看见: 1.一号窗口,3号窗口同时售出了10号票,原因为:一号窗口线程出了10号票,但是票的总数还未来得及减1,3号窗口也已经出票,此时还是10号票;
2.3号窗口,1号窗口出现了0号票和-1号票,我们给的判定机制为票数大于0才出票,这显然是不正常的,那么是为什么呢,因为,2号线程出1号票之前,票的余量是1,3号线程和1号线程也进入了出票流程,待得1号窗口出完票,此时剩余票数已经是0,所以出现上述结果。
怎么解决这一个问题,Java中采取了synchronized(同步锁) 这一个关键字,当一个线程正在用火车票这个资源时,给它一把锁,其他线程就不可以访问这个资源,待这个线程结束后,再把它交给另一个需要用到此资源的线程: For Example:
package Test;
public class TicketWindow extends Thread{
TicketCount tc;
private int name;
public TicketWindow(TicketCount tc,int name)
{
this.tc = tc;
this.name = name;
}
public void run()
{
while(true)
{
synchronized (tc) {
if(tc.count>0)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name+"号窗口已出票: "+tc.count--+"号票");
}
}
}
}
}
上面代码结果为:
1号窗口已出票: 10号票
2号窗口已出票: 9号票
3号窗口已出票: 8号票
3号窗口已出票: 7号票
2号窗口已出票: 6号票
2号窗口已出票: 5号票
2号窗口已出票: 4号票
1号窗口已出票: 3号票
1号窗口已出票: 2号票
1号窗口已出票: 1号票
由上可见,问题已完美解决!