Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Синхронизация потоков

5.0K
12 мая 2007 года
Fubu_By
74 / / 31.12.2006
Уменя есть вот такой метод:
Код:
static public synchronized void UpdateIspTraf(Long iduser, long isptraf){
    Session mysession = HibernateUtil.getSession();
    Transaction trans = mysession.beginTransaction();
    Query query = mysession.createQuery("from UserTable where iduser=" + iduser);

    Iterator results = query.iterate();

    UserTable us = (UserTable) results.next();
    us.setIsptraf(isptraf);
    mysession.update(us);
    trans.commit();
  }


Он служет для добавленяи в БД использованного трафика, который высчитываеться в потоке, трафик суммарный для нескольких потоков:

Код:
public void run() {
      try {
        System.out.println(id + " - about to get something from " + method.getURI());
        outfilename = path + outfilename;
        outfile = new File(outfilename);
        RandomAccessFile output = new RandomAccessFile(outfile, "rw");
        position = output.length();
        String zn = "bytes=" + position + "-";
        method.setRequestHeader("Range", zn);
        httpClient.executeMethod(method);
        switch (method.getStatusCode()){
          case 401 :
            Files.UpdateError(id, "401 Ошибка авторизации");
            break;//не коректная авторизация
          case 404 :
            Files.UpdateError(id, "404 Файл не доступен или отсутствует");
            break;
          default :{
            InputStream input = method.getResponseBodyAsStream();
            infilesize = method.getResponseContentLength();
            buffer = new byte[bloksize];
            output.seek(position);
            int kol;
            Files.UpdateStatus(id, 1);
            Long iduser = Files.GetIduser(id);
            while ( (kol = input.read(buffer)) != -1) {
              output.write(buffer, 0, kol);
              System.out.println(id + " - " + SkachenoProcentov(infilesize, output.length()) + "%");
              Files.UpdateSizefilenow(id, output.length());
              user.UpdateIspTraf(iduser, User.GetIspTraf(iduser) + kol);//вот, вызыветься сдесь
              Thread.sleep(500);
            }
            Files.UpdateStatus(id, 3);
          }
        }
        output.close();
      } catch (Exception e) {
        System.out.println(id + "!!!!! - error: " + e);
        Files.UpdateStatus(id, 2);
        Files.UpdateError(id, "Связь с сервером потеряна" + e.toString());
      } finally {
        method.releaseConnection();
        System.out.println(id + " - connection released");
      }
    }


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

как правильно синхронизировать, чтобы пока один поток не закончил работать с UpdateIspTraf(), другие потоки ожидали, и только после того как метод освабодился продолжали дальше записывать?
5.0K
24 мая 2007 года
Fubu_By
74 / / 31.12.2006
ниужели никто не знает?
3.7K
24 мая 2007 года
bioflash
169 / / 01.10.2005
Я не уверен в том, точно ли я понял твой вопрос, но мне кажется проблема в том, что ти хочеш синхронизировать не сам метод UpdateIspTraf(), а все визови в одном потоке. Если я прав, то тогда тебе нужно цикл while сделать synchronized. Или переписать функциональность по-другому.
5.0K
25 мая 2007 года
Fubu_By
74 / / 31.12.2006
обращения к UpdateIspTraf() происходят в разных потоках. и она прикрасно вызывается но вот почемуто не работает синхронизация что-то не так делаю, с пробовал wait() и notify(), тоже почемуто не получается
30K
25 мая 2007 года
ajtec
1 / / 24.05.2007
Ты о динамических прокси классах что-то слышал?
Все транзакции лучше оформлять в одном классе. Который потом звернется в прокси.
А уже сам вызов должен быть синхронизирован.
И в методе UpdateIspTraf явно не хватает обработки исключения и ролбека.

А если совсем не пойдет. Можешь сделать поток с очередью и все свои результаты из разных потоков засовывать в эту очередь а уже сам этот поток из очереди будет впихивать твои результаты в UpdateIspTraf
5.0K
25 мая 2007 года
Fubu_By
74 / / 31.12.2006
Цитата: ajtec
Ты о динамических прокси классах что-то слышал?
Все транзакции лучше оформлять в одном классе. Который потом звернется в прокси.
А уже сам вызов должен быть синхронизирован.
И в методе UpdateIspTraf явно не хватает обработки исключения и ролбека.

А если совсем не пойдет. Можешь сделать поток с очередью и все свои результаты из разных потоков засовывать в эту очередь а уже сам этот поток из очереди будет впихивать твои результаты в UpdateIspTraf


о динамических классах в первый раз слышу.(оставь ссылку со статьёйна русскум, если есть)
а зачем там обработка исклшючений?мне бы сделать сначалонормальный вызов...

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог