请教关于类锁的同步问题

NewLifefromNowon 2012-09-18 10:16:02
有个作业要求实现多个售票站卖火车票,我想把票设为静态变量,然后通过一个类方法来取票来保证同步,但是给类方法上锁以后,不同实例的线程取票时还会出错,卖出第-1张票,请问问题出在哪里呢?是类方法的调用方式有问题么?
代码如下:
public class Tickets extends Thread{
private static int tickets=100;
public static synchronized void sellOne(String name){
System.out.println(name+"_________"+(tickets--));
}
public void run(){
while(tickets>0)
{
String name=Thread.currentThread().getName();
sellOne(name);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new Tickets().start();
new Tickets().start();
new Tickets().start();
new Tickets().start();
}

}
...全文
152 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
package comticket;

public class NewThreadTicket implements Runnable {
private int ticket = 100;
// 在java中所有的对象都是一把锁
//private Object obj = new Object();
public void run() {
while (ticket!=0) {
sell();
/*
* //枷锁 synchronized (obj) { if (ticket > 0) { try {
* Thread.sleep(30); } catch (InterruptedException e) {
* e.printStackTrace(); }
* System.out.println(Thread.currentThread().getName() + "卖出第" +
* ticket + "张"); ticket--; }
*/
}
}

public synchronized void sell() {
if (ticket > 0) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出第"
+ ticket + "张");
ticket--;
}
}
}




package comticket;

public class Test {
public static void main(String[] args) {
//创建对象
NewThreadTicket ntt = new NewThreadTicket();
//创建四个线程
new Thread(ntt).start();
new Thread(ntt).start();
new Thread(ntt).start();
new Thread(ntt).start();
}
}
LogicTeamLeader 2012-09-19
  • 打赏
  • 举报
回复
以上都对!lz还没有理解锁的真正含义。
龙四 2012-09-19
  • 打赏
  • 举报
回复
只是锁定了sellOne,不能同时进sellOne,但是run方法并没有锁啊,他们可以同时进run,执行while判断

[Quote=引用 4 楼 的回复:]

当tickets=1时,两个线程同时去判断tickets发现他都大于0所以两个线程都调用sellOne方法,当一个线程执行完后另一个线程在去执行(注意这里后一个线程他是停在sellOne方法上的,所以他不会在跑回去判断tickets是否大于0而是直接去实行sellOne方法,就出现-1了)。
[/Quote]
龙泉剑 2012-09-19
  • 打赏
  • 举报
回复
public static synchronized void sellOne(String name){
if(tickets>0)
System.out.println(name+"_________"+(tickets--));
}
书断华 2012-09-18
  • 打赏
  • 举报
回复
可能不是同时 而是前一个线程还没执行到tickets--时,下一个线程又去判断tickets是否大于0。
书断华 2012-09-18
  • 打赏
  • 举报
回复
当tickets=1时,两个线程同时去判断tickets发现他都大于0所以两个线程都调用sellOne方法,当一个线程执行完后另一个线程在去执行(注意这里后一个线程他是停在sellOne方法上的,所以他不会在跑回去判断tickets是否大于0而是直接去实行sellOne方法,就出现-1了)。
Adminduan 2012-09-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

竞态条件问题,while(tickets>0)与tickets--不是原子的

当tickets等于1,两个线程同时发现tickets>0,都进了sellOne方法,就导致这个问题了
[/Quote]

你好,麻烦问一下 锁定方法不是当有下一个线程访问的时候不是在方法外面等候吗?这里为什么会访问进来那?
xiars123 2012-09-18
  • 打赏
  • 举报
回复
	public static synchronized void sellOne(String name) {
while (tickets > 0) {
System.out.println(name + "_________" + (tickets--));
}
}

public void run() {
String name = Thread.currentThread().getName();
sellOne(name);
}

这样应该ok了
龙四 2012-09-18
  • 打赏
  • 举报
回复
竞态条件问题,while(tickets>0)与tickets--不是原子的

当tickets等于1,两个线程同时发现tickets>0,都进了sellOne方法,就导致这个问题了

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧