您的位置:首页 > 编程语言 > Java开发

Java中线程的安全问题

2014-04-16 15:46 295 查看
假设我们现在要用代码实现这个场景:

售票处共有100张票,同时开设4个窗口同时售票,知道票售完为止

我们暂且将这种场景想象成线程的实现过程:四个线程同时售票,直到售完为止

使用Java API文档中线程使用的第一种方法,我们定义一个继承了Thread类的类Ticket,并重写run方法:

class Ticket extends Thread

{

private static int num=100;

public void sale()

{

while(true)

{

if(num>0)

{

System.out.println(Thread.currentThread().getName()+"Sale:"+num--);

}

if(num==0)

{

//Thread.currentThread().stop();

break;

}

}

}

public void run()

{

sale();

}



在main函数中实例化四个Ticket对象,并同时开启这四个线程

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();

}

运行代码,结果截图如下:



运行结果好像有些问题:为什么售票的顺序是错乱的呢?

问题的原因在于cmd也是一个程序,程序的执行是要依靠CPU的执行权,程序的运行是要靠CPU的不断切换执行权而运行的

在CPU在不同程序中不断的切换执行权的时候就会导致控制台结果输出的错乱。

好,排除了这个"异象",那程序的运行结果大概就是我们想要的结果了吧?从100递减到1,貌似没有什么问题。

现在我们在程序运行到run方法中的if(num>0)后让线程休息一段时间,将Ticket类改为以下代码:

class Ticket extends Thread

{

private static int num=100;

public void sale()

{

while(true)

{

if(num>0)

{

try

{

Thread.sleep(20);

}

catch (InterruptedException e)

{

System.out.println("Error:"+e);

}

System.out.println(Thread.currentThread().getName()+"Sale:"+num--);

}

if(num==0)

{

//Thread.currentThread().stop();

break;

}

}

}

public void run()

{

sale();

}

}

运行结果,就会出现如图所示的灵异现象:



程序的结果居然出现了负值?!就像你买到的火车票是负数座位一样令人毛骨损人!见鬼了吗??

前面我们说过,程序的执行是在CPU不断切换执行权的情况下实现的,当某些线程在执行进入if(){}结果内,

让线程sleep()一段时间,这时就有可能有其它线程在这段时间内也进入了if(num>0){}内,因为进入{}的都满足了num>0

的条件,然后等线程休息结束后得到了执行权继续往下执行,就会把num值变成负数,这也就是线程灵异现象的产生原因。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: