复习以前学过的java多线程时,看到一如下同步卖票程序:
很显然此处还没有考虑多线程的同步问题。
而且进过编译执行,得到的结果貌似很成功。心中既疑惑又窃喜。我一直在想老师为什么要用while(true)循环呢(看视频,老师未进行说明)?
既然程序没有考虑线程的同步,肯定是不对的,那么就要给他同步一下,用synchronized()同步代码块。
我们知道同步必须要明确哪些数据是共享的,哪些代码是操作共享数据的。
上例中共享数据是tic=1000,操作共享数据的代码为tic>0和tic--。
那么tic>0和tic--都必须要封装到synchronized()同步代码块中。
这时候问题就出来了,
对于while(true),若将run()方法改写为
可得到我们意想的结果。
但是对于while(tic>0),若将run()方法写成
这显然是不正确的,因为这样线程并未得到同步,会出现票为负数的情况,验证错误。
那么这样了:
看起来很憋屈,结果也很悲剧。根本不可能多线程执行,因为当某一个线程拿到锁后,他给一股脑的全给干完了,其他线程根本无法执行。显然也不对。
那么这样看来while(ture)做循环语句的条件,看来是为了控制多线程同步执行,而去很关键。当然以上结果只是我的看法,也许,它还有更重要的作用只是我不知道而已,希望各位
朋友若有更好的答案,留言给我。
菜鸟自学,不胜感激。
还有一个问题:
一般此处的catch应该怎么处理,我一直都这样空着,应该不妥吧?
class Tickets implements Runnable
{
private int tic;
Object obj = new Object();
Tickets(int tic)
{
this.tic = tic;
}
public void run()
{
while(true)
{
if(tic>0)
{
System.out.println(Thread.currentThread().getName()+"\t"+tic--);
}
}
}
}
class TicketDemo
{
public static void main(String[] args)
{
Tickets t = new Tickets(1000);
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
Thread t5 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
很显然此处还没有考虑多线程的同步问题。
看到此处时
public void run()
{
while(true)
{
if(tic>0)
{
System.out.println(Thread.currentThread().getName()+"\t"+tic--);
}
}
}
我突想到为什么这个run()方法的while循环不直接写成
public void run()
{
while(tic>0)
{
System.out.println(Thread.currentThread().getName()+"\t"+tic--);
}
}
而且进过编译执行,得到的结果貌似很成功。心中既疑惑又窃喜。我一直在想老师为什么要用while(true)循环呢(看视频,老师未进行说明)?
既然程序没有考虑线程的同步,肯定是不对的,那么就要给他同步一下,用synchronized()同步代码块。
我们知道同步必须要明确哪些数据是共享的,哪些代码是操作共享数据的。
上例中共享数据是tic=1000,操作共享数据的代码为tic>0和tic--。
那么tic>0和tic--都必须要封装到synchronized()同步代码块中。
这时候问题就出来了,
对于while(true),若将run()方法改写为
public void run()
{
while(true)
{
synchronized(obj)
{
if(tic>0)
{
try
{
Thread.sleep(10);
}
catch (Exception e)
{
}
System.out.println(Thread.currentThread().getName()+"\t"+tic--);
}
}
}
}
可得到我们意想的结果。
但是对于while(tic>0),若将run()方法写成
public void run()
{
while(tic>0)
{
synchronized(obj)
{
try
{
Thread.sleep(10);
}
catch (Exception e)
{
}
System.out.println(Thread.currentThread().getName()+"\t"+tic--);
}
}
}
这显然是不正确的,因为这样线程并未得到同步,会出现票为负数的情况,验证错误。
那么这样了:
public void run()
{
synchronized(obj)
{
while(tic>0)
{
try
{
Thread.sleep(10);
}
catch (Exception e)
{
}
System.out.println(Thread.currentThread().getName()+"\t"+tic--);
}
}
}
看起来很憋屈,结果也很悲剧。根本不可能多线程执行,因为当某一个线程拿到锁后,他给一股脑的全给干完了,其他线程根本无法执行。显然也不对。
那么这样看来while(ture)做循环语句的条件,看来是为了控制多线程同步执行,而去很关键。当然以上结果只是我的看法,也许,它还有更重要的作用只是我不知道而已,希望各位
朋友若有更好的答案,留言给我。
菜鸟自学,不胜感激。
还有一个问题:
try
{
Thread.sleep(10);
}
catch (Exception e)
{
}
一般此处的catch应该怎么处理,我一直都这样空着,应该不妥吧?