2015-12-13 1 views
0

Я в основном пытаюсь реализовать пример реальной жизни нескольких людей, бронирующих одно онлайн-такси. Здесь, в моем коде, у меня есть 3 класса - такси, клиент и сервер.
Должно быть несколько клиентов (нитей) и одно такси. Но я не могу этого сделать. Каждый раз, когда я создаю нового клиента, создается новый экземпляр такси.
Это класс такси код-

Не удалось добиться синхронизации в многопоточности

public class taxi { 
     boolean BOOKED=false; 
     String id; 
     void book(){ 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      BOOKED=true; 
      System.out.println("Customer "+Thread.currentThread().getName()+" BOOKED taxi"); 
     } 

     void release(){ 
      BOOKED=false; 
      System.out.println("Customer "+Thread.currentThread().getName()+" RELEASED taxi"); 
     } 

     void setId(String id){ 
      this.id=id; 
     } 

     String getId(){ 
      return id; 
     } 

    } 

класс клиента код-

public class customer extends Thread { 
    taxi t=new taxi(); 
     public void run(){ 
      //System.out.println(t.hashCode()); 
      t.setId(Thread.currentThread().getName()); 
      System.out.println("Customer "+Thread.currentThread().getName()+" trying to BOOK taxi"); 
      t.book(); 
      System.out.println("Customer "+Thread.currentThread().getName()+" is currently USING taxi"); 

      try { 


Thread.sleep(2000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("Customer "+Thread.currentThread().getName()+" RELEASING taxi"); 
     t.release(); 
     try { 
      Thread.sleep(3000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("taxi used by customer "+Thread.currentThread().getName()+" set id to "+t.getId()); 
    } 



} 

серверный класс код-

public class server { 

public static void main(String args[]){ 

     customer A=new customer(); 
     customer B=new customer(); 
     customer C=new customer(); 
     customer D=new customer(); 
     Thread t=new Thread(); 
     A.setName("A"); 
     B.setName("B"); 
     C.setName("C"); 
     D.setName("D"); 

     A.start(); 
     B.start(); 
     C.start(); 
     D.start(); 




    } 


    } 


Это мой output-

Customer B trying to BOOK taxi 
Customer D trying to BOOK taxi 
Customer A trying to BOOK taxi 
Customer C trying to BOOK taxi 
Customer B BOOKED taxi 
Customer A BOOKED taxi 
Customer A is currently USING taxi 
Customer D BOOKED taxi 
Customer D is currently USING taxi 
Customer B is currently USING taxi 
Customer C BOOKED taxi 
Customer C is currently USING taxi 
Customer C RELEASING taxi 
Customer C RELEASED taxi 
Customer D RELEASING taxi 
Customer D RELEASED taxi 
Customer A RELEASING taxi 
Customer A RELEASED taxi 
Customer B RELEASING taxi 
Customer B RELEASED taxi 
taxi used by customer D set id to D 
taxi used by customer C set id to C 
taxi used by customer A set id to A 
taxi used by customer B set id to B 


Как вы можете видеть, идентификатор каждого такси отличается от другого.
Просьба помочь.

+0

Как вы думаете, 'такси t = новое такси();' как поле внутри 'customer'? –

+0

он создает экземпляр такси в клиенте. Я знаю, что это основная причина моей проблемы, но я не могу понять, как это сделать. –

+1

Создайте один экземпляр «taxi» и поделитесь им с вашими «клиентскими» экземплярами.Вы узнали о аргументах конструктора раньше? –

ответ

1

Некоторые важные моменты, касающиеся вашего кода:

  1. Вы должны создать только один экземпляр класса такси и удалить переменную экземпляра такси из класса Customer и инстанцирование такси в классе сервера.
  2. измените свой класс клиентов на работу с общим такси. Вы можете создать параметризованный конструктор в классе Customer для инициализации общего такси.
  3. setId следует вызвать внутри книги методов, чтобы идентификатор такси мог быть изменен только темой, которая хочет заказать такси.

Вы можете использовать ожидание/уведомит механизм таким образом, в классе такси для достижения синхронизации:

public class Taxi { 
    Boolean BOOKED = false; 
    String id; 

    void book() throws InterruptedException { 
     synchronized (this) { 
      while (BOOKED) { 
       this.wait(); 
      } 
      try { 
       setId(Thread.currentThread().getName()); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      BOOKED = true; 
      System.out.println("Customer " + Thread.currentThread().getName() + " BOOKED taxi"); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 

    void release() throws InterruptedException { 
     synchronized (this) { 
      BOOKED = false; 
      System.out.println("Customer " + Thread.currentThread().getName() + " RELEASED taxi"); 
      this.notifyAll(); 
     } 
    } 

    void setId(String id) throws InterruptedException { 
     System.out.println("SETTING ID TO CUSTOMER " + Thread.currentThread().getName()); 
     this.id = id; 
    } 

    String getId() { 
     return id; 
    } 
} 

Заказчик:

public class Customer extends Thread { 
    Taxi taxi; 

    public Customer(Taxi taxi){ 
     this.taxi = taxi; 
    } 

    public void run(){ 
     //System.out.println(t.hashCode()); 

     System.out.println("Customer "+Thread.currentThread().getName()+" trying to BOOK taxi"); 
     try { 
      taxi.book(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("Customer "+Thread.currentThread().getName()+" is currently USING taxi"); 

     try { 
      Thread.sleep(2000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("Customer "+Thread.currentThread().getName()+" RELEASING taxi"); 
     try { 
      taxi.release(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     try { 
      Thread.sleep(3000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Я предполагаю, что вы неправильно поняли проблему. Проблема здесь в том, что в конечном итоге у меня есть несколько экземпляров класса такси, и, поскольку класс такси действует как мои данные, я не могу иметь несколько экземпляров. –

+0

Вы должны создать только один экземпляр класса Taxi и удалить переменную экземпляра такси из класса Customer и создать экземпляр Taxi в классе сервера – akki

+0

Хорошо. Затем, как я могу использовать этот экземпляр дальше, чтобы все потоки работали на том же экземпляре –

1

Я думаю, класс такси не обязательно должен быть нитью. путем создания класса такси в качестве общего ресурса (одна тонна с синхронизированным методом) среди всех других потоков клиентов, мы можем добиться ожидаемой синхронизации в многопоточности.

+0

Извините, что это была ошибка. Теперь я отредактировал его. –

+0

Не могли бы вы рассказать мне, как использовать такие методы, как wait() и notify() здесь –

1

Почему вы создаете каждый раз, когда новое такси в клиенте? Проблема заключается в следующем: taxi t=new taxi();. Просто передайте такси конструктором или сделайте его глобальным или что-то в этом роде. Таким образом, каждый клиент будет использовать одно и то же такси. Кроме того, потоки опасны, поэтому вы должны быть очень осторожны с ними. У вас нет синхронизации. Я предлагаю вам не понимать, как правильно использовать потоки. Я предлагаю вам прочитать о synchronize, volatile, wait, notify, notifyAll и поэкспериментировать и попробовать некоторые основные примеры. Я считаю, что первые два были хорошо описаны в Head First Java. Offtopic: вы должны следовать соглашениям при наименовании переменных и методов.

+0

Спасибо большое :). –