public class ticketTread implements Runnable{ static boolean flag=true;
int count=200;
public void run()
{
while(flag&&count>=0)
{
synchronized(this)
{
System.out.println("这是"+Thread.currentThread().getName()+"在卖"+count+"张票");
count--;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void safeStop()
{
flag=false;
}
}import java.io.IOException;
public class ticketDemo { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ticketTread tr=new ticketTread();
Thread t1=new Thread(tr);
Thread t2=new Thread(tr);
Thread t3=new Thread(tr);
Thread t4=new Thread(tr);
t1.start();
t2.start();
t3.start();
t4.start();
//阻塞
try {
System.in.read();
ticketTread.safeStop();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
// 结果打印出了
int count=200;
public void run()
{
while(flag&&count>=0)
{
synchronized(this)
{
System.out.println("这是"+Thread.currentThread().getName()+"在卖"+count+"张票");
count--;
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void safeStop()
{
flag=false;
}
}import java.io.IOException;
public class ticketDemo { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ticketTread tr=new ticketTread();
Thread t1=new Thread(tr);
Thread t2=new Thread(tr);
Thread t3=new Thread(tr);
Thread t4=new Thread(tr);
t1.start();
t2.start();
t3.start();
t4.start();
//阻塞
try {
System.in.read();
ticketTread.safeStop();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}
// 结果打印出了
public void run() { while (flag && count >= 0) {
synchronized (this) {
if(count >= 0){
System.out.println("这是" + Thread.currentThread().getName()
+ "在卖" + count + "张票");
count--;
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
修改run方法为:public void run()
{
synchronized(this)
{
while(flag&&count>=0)
{
System.out.println("这是"+Thread.currentThread().getName()+"在卖"+count+"张票");
count--;
try {
this.wait(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}或者在同步块内再加上判断。public void run()
{
while(flag&&count>=0)
{
synchronized(this)
{
if(flag&&count>=0){ //这里再加上判断
System.out.println("这是"+Thread.currentThread().getName()+"在卖"+count+"张票");
count--;
}else{
return ;
} }
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
正解等待的时候,,count很可能已经改变了
the right answer~
while(flag&&count>=0)此时满足条件遇到锁第二个线程等待,继续执行第一个线程count--,此时count为-1,然后第二个线程抢到资源执行输出语句,但此时count为-1了,所以就错了。解决方法就是把while语句也锁进去,或在进行一次判别。
希望能帮助楼主
{
/*synchronized放在while循环体的内部,假设当前线程是t1,执行到count == 0时 while执行完但还未进入到synchronized块的时候可能会被其他线程抢占此资源 假设是t2,执行run()方法打印出count == 0,然后count-- ,此时count == -1,但此时对于t1来说while语句已经判断了!所以对于t1来说它会直接调用System.out.println()方法,打印的却是count为-1时的语句*/
synchronized(this)正确的解决办法是将synchronized(this)放在while语句之外,至于为什么,请楼主自己思考。