|
需求:编写三各类Ticket、SealWindow、TicketSealCenter分别代表票信息、售票窗口、售票中心。售票中心分配一定数量的票,由若干个售票窗口进行出售。 运行的时候有重复的票号,我已经在卖票的方法上添加了synchronized关键字,还是会出现问题,但是我找不到问题出在哪里了,谢谢大家了 public class TicketDemo {
public static void main(String[] args) {
new Thread(new SealWindow("1号窗口")).start();
new Thread(new SealWindow("2号窗口")).start();
new Thread(new SealWindow("3号窗口")).start();
new Thread(new SealWindow("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 {
private String ticketname;
TicketSealCenter tsc = null;;
public SealWindow(String ticketname){
this.ticketname = ticketname;
tsc = TicketSealCenter.getInstance();
}
public void sellTicket(){
while(!tsc.hasTicket()){
System.out.println(ticketname+"卖出了第" + tsc.getid()+"号票!");
if (tsc.hasTicket()) {
System.out.println(ticketname+"的票已卖完!");
}
}
}
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);
sumticket--;
}else {
flag =true;
}
return flag;
}
public int getid(){
return ticket.getTicketid();
}
}
|
|
![]() |
因为你的synchronized是加在对象上的,但是你在建线程的时候,又新建了好几个匿名对象,这就意味着每个对象都有它自己的synchronized,所以这几个线程也就不互斥,因为它们不共享synchronized。正确的做法是只需要建一个对象,然后让这几个线程共享一个对象。像“1号窗口”、“2号窗口”可以设置为线程的名字,而不是对象的属性。
|
![]() 15分 |
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();
}
}
|
![]() 5分 |
您说的不对吧,不是因为创建了多个对象,而是因为 |
![]() 5分 |
恩 主要楼主用的是单例设计模式,不管创建多少个SealWindow,共享的都是一个TicketSealCenter对象。你的意思我在上述代码中已经有所体现了。
|
![]() 5分 |
很简单的代码,撸主给弄好凌乱,很简单的锁机制,撸主却乱加。
减票方法你是加锁了,可是获取票的方法你考虑过么? 如果一个线程都执行了public static synchronized boolean hasTicket()这个方法后,执行权交给另一个线程,另一个线程也跑了这个方法,后面类推,接着多个线程开始执行public int getid()方法,你觉得票是多了呢,还是少了呢? |
![]() |
多谢了 我刚开始学java 思路有些混乱 之后自己又缕清了思路 重新写了下 现在不会出现安全问题了 还是十分的感谢你 |

