Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> synchronized, синхронизация поля или метода 
:(
    Опции темы
cube
Дата 27.7.2009, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 11.4.2007

Репутация: 2
Всего: 3



Наверное у всех когда-то наступают проблемы с синхронизацией, пишу проект, пишу один, времени улучшать что-то как всегда нет, но наступает время когда делать это приходится...

Мой проект клиент-сервер rmi приложение, на сервере есть "объекты" и "списки объектов" которыми я "орудую" с клиента.

Список объектов (в данном случае список услуг)

Код

public class ServiceListImpl extends HObjectsListImpl implements ServiceList
{
  public PreparedStatement removeStmt;
  public PreparedStatement createStmt;
  public PreparedStatement updateStmt;
  public PreparedStatement getIdStmt;

  public ServiceListImpl() throws RemoteException {
    super();
    try {
      Connection c = ServerImpl.getInstance().getConnection();
      removeStmt = c.prepareStatement("DELETE FROM services WHERE id=?");
      createStmt = c.prepareStatement("INSERT INTO services (name, price, group_service_id) VALUES(?,?,?)");
      updateStmt = c.prepareStatement("UPDATE services SET name=?, price=?, group_service_id=? WHERE id=?");
      getIdStmt = c.prepareStatement("SELECT max(id) FROM services");
    } catch (SQLException ex) {
      ex.printStackTrace();
    }
  }
  @Override
  public Service getEmptyService() throws RemoteException {return new ServiceImpl(this);}


Сам объект (в данном случае услуга)

Код

public class ServiceImpl extends HObjectImpl implements Service
{
  private String name;
  private Double price;
  private Integer groupServiceId;

  private ServiceListImpl list;

  public ServiceImpl(ServiceListImpl list) throws RemoteException {
    super(list);
    this.list = list;
  }

  @Override
  public String getName() throws RemoteException {
    return name;
  }

  @Override
  public void setName(String name) throws RemoteException {
    this.name = name;
  }

  @Override
  public Double getPrice() throws RemoteException {
    return price;
  }

  @Override
  public void setPrice(Double price) throws RemoteException {
    this.price = price;
  }

  @Override
  public Integer getGroupServiceId() throws RemoteException {
    return groupServiceId;
  }

  @Override
  public void setGroupServiceId(Integer groupServiceId) throws RemoteException {
    this.groupServiceId = groupServiceId;
  }

  @Override
  public void removeDB() throws RemoteException {
    try{
      list.removeStmt.setInt(1, getID());
      list.removeStmt.executeUpdate();
      list.removeHObject(this);
      ((ServerImpl)ServerImpl.getInstance()).fireServicesChanged();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
  }

  @Override
  public void createDB() throws RemoteException {
    try{
      list.createStmt.setString(1, name);
      list.createStmt.setDouble(2, price);
      if (groupServiceId!=null)
        list.createStmt.setInt(3, groupServiceId);
      else
        list.createStmt.setNull(3, java.sql.Types.INTEGER);
      list.createStmt.executeUpdate();
      ResultSet rset = list.getIdStmt.executeQuery();
      if(rset.next())this.setID(rset.getInt(1));
      rset.close();
      list.addHObject(this);
      ((ServerImpl)ServerImpl.getInstance()).fireServicesChanged();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
  }

  @Override
  public void updateDB() throws RemoteException {
    try{
      list.updateStmt.setString(1, name);
      list.updateStmt.setDouble(2, price);
      if (groupServiceId!=null)
        list.updateStmt.setInt(3, groupServiceId);
      else
        list.updateStmt.setNull(3, java.sql.Types.INTEGER);
      list.updateStmt.setInt(4, getID());
      list.updateStmt.executeUpdate();
      list.updateHObject(this);
      ((ServerImpl)ServerImpl.getInstance()).fireServicesChanged();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
  }
}


все нормально работает, но если обратить внимание например на метод  removeDB() то там следующий код он работает неправильно (если несколько клиентов одновременно удаляют объект типа услуга)

list.removeStmt.setInt(1, getID());
list.removeStmt.executeUpdate();

как синхронизировать методы, или поля этих классов, чтобы пока не произойдет удаления объекта, другой клиент "ждал" доступа к удалению

PM MAIL   Вверх
_sten_
Дата 31.7.2009, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 184
Регистрация: 29.9.2006

Репутация: нет
Всего: 3



ну можно попробовать синхронизировать по ServerImpl.getInstance() типа
Код

synchronized(ServerImpl.getInstance()){
     .....
}

если конечно ServerImpl.getInstance() - синголтон, если нет то добавь просто какое то статическое поле и синхронизируй по нем, будет что вроде:
Код

private static final Object monitor = new Object();
....
 public void removeDB() throws RemoteException {
  synchonized(monitor){
    ....
  }
 }


в обще синхронизировать поле нельзя... Есть только синхронизированные блоки, типа:
Код

 synchonized(monitor){
    ....
  }

где в скобках указывается объект монитор которого будет захвачен. Два потока не могут захватить монитор одного объекта одновременно - второй будет ждать, пока первый не выйдет из блока.
Можно также синхронизировать метод добавив перед именем synchronized, но это все равно что синхронизироваться по this

В обще в твоем случае возможно синхронизироваться надо в базе, типа select for update или что то мудрить с уровнями изоляции транзакций
--------------------
WARNING: Condition 'to_be || !to_be' is always 'true' !
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0476 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.