因为你的synchronized是加在对象上的,但是你在建线程的时候,又新建了好几个匿名对象,这就意味着每个对象都有它自己的synchronized,所以这几个线程也就不互斥,因为它们不共享synchronized。正确的做法是只需要建一个对象,然后让这几个线程共享一个对象。像“1号窗口”、“2号窗口”可以设置为线程的名字,而不是对象的属性。
解决方案 »
- spring容器中能拥有两个同种类型的bean吗。我有两个dao类同时实现一个接口,这两个接口注入时报了异常。
- 如何记录用户的操作
- struts2.action.extension 配置
- struts 503错误
- 我最近用jsp在做网上订餐系统,谁有相关的制作步骤可以分享给我的,先谢谢大家!
- 局域网教学的开发问题?
- sql语句查询日期的时候。用什么函数可以只只查询小时、分和秒
- Java错误页面的处理
- javamail发送和接收邮件的身份验证问题。。给100分,急!
- 讨论:IBM WebSphere,大侠请进!
- java后台怎么给android前台分批次传值(值不重复)
- gson出问题..求大牛啊!!!
public class TicketDemo {
public static void main(String[] args) {
SealWindow myWindow=new SealWindow();
new Thread(myWindow,"1号窗口").start();
new Thread(myWindow,"2号窗口").start();
new Thread(myWindow,"3号窗口").start();
new Thread(myWindow,"4号窗口").start();
}
}
//票信息
class Ticket {
private static int ticketid;
public static int getTicketid() {
return ticketid;
}
public static void setTicketid(int ticket) {
ticketid = ticket;
}
}
//售票窗口
class SealWindow implements Runnable {
TicketSealCenter tsc = null;
public SealWindow(){
tsc = TicketSealCenter.getInstance();
}
public void sellTicket(){
while(!tsc.hasTicket()){
// System.out.println(Thread.currentThread().getName()+"卖出了第" + tsc.getid()+"号票!");
if (tsc.hasTicket()) {
System.out.println(Thread.currentThread().getName()+"的票已卖完!!");
}
}
}
public void run() {
sellTicket();
}
}
//售票中心
class TicketSealCenter {
private static TicketSealCenter tsc = new TicketSealCenter();
private static Ticket ticket = new Ticket();
private static int sumticket = 100;
private static boolean flag = false;
private TicketSealCenter(){}
public static TicketSealCenter getInstance(){
return tsc;
}
//询问是否有票,设置票面ID,并返回该ID
public static synchronized boolean hasTicket(){
if(sumticket > 0){
ticket.setTicketid(sumticket);
System.out.println(Thread.currentThread().getName()+"卖出了第" + tsc.getid()+"号票!");
sumticket--;
}else {
flag =true;
}
return flag;
}
public int getid(){
return ticket.getTicketid();
}
}
您说的不对吧,不是因为创建了多个对象,而是因为
while(!tsc.hasTicket()){
System.out.println(ticketname+"卖出了第" + tsc.getid()+"号票!");
这句并不能保证调用完成tsc.hasTicket方法之后马上执行输出语句,所以要不给这句上面加锁,但是只能加静态锁。或者就是把这句输出语句加到tsc.hasTicket他的实现里面。
减票方法你是加锁了,可是获取票的方法你考虑过么?
如果一个线程都执行了public static synchronized boolean hasTicket()这个方法后,执行权交给另一个线程,另一个线程也跑了这个方法,后面类推,接着多个线程开始执行public int getid()方法,你觉得票是多了呢,还是少了呢?