您的位置:首页 > 其它

关于多线程中synchronized的使用位置

2016-12-23 23:02 423 查看
在练习多线程之售票的时候,对于synchronized的使用有些困惑,因为我是用以下代码:

public class ThreadDemo5 {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
saleTicket_5 st = new saleTicket_5();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
Thread t3 = new Thread(st);
Thread t4 = new Thread(st);
t1.start();
t2.start();
t3.start();
t4.start();
}

}

class saleTicket_5 implements Runnable {
private int ticket = 1000;
Object obj = new Object();

public void run() {
synchronized (obj) {

while (ticket > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "****"
+ ticket--);
}
}
}
}

synchronized在此虽然将共享资源的代码块上锁,但是synchronized上锁之后,线程需要把synchronized里面的代码块执行完毕后才能释放锁,此代码块里面是一个循环,这就造成了最后的结果只有Thread-0线程在执行的情况。

之后对其进行修改:

public class ThreadDemo5 {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
saleTicket_5 st = new saleTicket_5();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
Thread t3 = new Thread(st);
Thread t4 = new Thread(st);
t1.start();
t2.start();
t3.start();
t4.start();
}

}

class saleTicket_5 implements Runnable {
private int ticket = 1000;
Object obj = new Object();

public void run() {

while (true) {
synchronized (obj) {
if (ticket > 0) {

try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "****" + ticket--);
} else
break;
}

}
}
}


需要注意的是synchronized里面需要包含全部的共享资源,以保证对共享资源操作的原子性,另外 不要忘记退出while循环
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: