结果有买到同样票的和0的情况……求解,why?
public class Shop
{
public static void main(String[] args)
{
Outer o=new Outer();
o.getSale("s1:").start();
o.getSale("s2:").start();
}
}class Outer
{
private int ticket=20;
public Thread getSale(String s)
{
return new Sale(s);
}
private class Sale extends Thread
{
Sale(String s)
{
super(s);
}
public synchronized void run()
{
//int tmp=ticket;
while(ticket>0)
{
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(getName()+" ticket "+ticket--);
//ticket=tmp;
}
}
}
}
public class Shop
{
public static void main(String[] args)
{
Outer o=new Outer();
o.getSale("s1:").start();
o.getSale("s2:").start();
}
}class Outer
{
private int ticket=20;
public Thread getSale(String s)
{
return new Sale(s);
}
private class Sale extends Thread
{
Sale(String s)
{
super(s);
}
public synchronized void run()
{
//int tmp=ticket;
while(ticket>0)
{
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(getName()+" ticket "+ticket--);
//ticket=tmp;
}
}
}
}
{
public static void main(String[] args)
{
Outer o=new Outer();
o.getSale("s1:").start();
o.getSale("s2:").start();
}
}class Outer
{
public Thread getSale(String s)
{
return new Sale(s);
}
private class Sale extends Thread
{
Sale(String s)
{
super(s);
}
synchronized(this)
{
private int ticket=20;
public void run()
{
//int tmp=ticket;
while(ticket>0)
{
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(getName()+" ticket "+ticket--);
//ticket=tmp;
}
}
}
}
}改动后编译都不通过了
{
public static void main(String[] args)
{
Outer o=new Outer();
o.getSale("s1:").start();
o.getSale("s2:").start();
}
}
class Outer
{
public Thread getSale(String s)
{
return new Sale(s);
}
private class Sale extends Thread
{
Sale(String s)
{
super(s);
}
synchronized(this) //这个是在类里定义的,怎么可能通过,你需要在一个方法里定义他。run里。
{ //不过你用this,貌似依旧不能解决问题。
//最好Outer类中定义一个object对象,然后用他做
//同步锁,这样就保证了两个锁的一致..
private int ticket=20;
public void run()
{
//int tmp=ticket;
while(ticket>0)
{
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(getName()+" ticket "+ticket--);
//ticket=tmp;
}
}
}
}
}
{ while (ticket > 0)
{
synchronized (o)
{
System.out.println(getName() + " ticket " + ticket--);
try
{
sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
} }
改成这样就行啦。不过sleep要在System.out.println(....)的下面。
如果在前面的话,线程1进去之后,先休息1秒。
如果当时刚好是ticket = 1.
这个时候,run方法被线程2执行,他进去之后,发现ticket = 1; 于是可以往下执行去。线程1再次从sleep初唤醒。
就会输出0。。
由于sleep()方法是Thread类的方法,因此它不能改变对象的机锁。所以当在一个Synchronized方法中调用sleep()时,线程虽然休眠了,但是对象的机锁没有被释放,其他线程仍然无法访问这个对象
this是代表对象,你创建一个新的对象,this自然不同了。除非是访问同一个对象创的方法。否则this是没有效果的。