Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > возможен ли здесь DeadLock?


Автор: W0LF 22.1.2008, 22:59
Доброго времени суток. Вроде здесь не должно возникать дедлока, но чет такое предчуствие, что возникает. Просто зависает и все, и то, это по праздникам бывает, отловить не могу.Вот код - 
Код

public void addPictureData(int parentGalleryId, ByteArrayOutputStream imageBytes, String pictureUrl, Date date) {
        
        synchronized (monitor/*финал объект*/) {

            if (parGalIdPool.size() > 5) {

                try {
                    monitor.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (this) {
                if (date != null) {
                    Logger.log(ScaleImagesSaveToDbThread.class.getName(), "!!!adding icon to pool url = " + pictureUrl);
                } else {
                    Logger.log(ScaleImagesSaveToDbThread.class.getName(), "!!!adding picture to pool url = " + pictureUrl);
                }
                parGalIdPool.add(parentGalleryId);
                imageBytesPool.add(imageBytes);
                pictureUrlPool.add(pictureUrl);
                datePool.add(date);
                this.notify();
            }

        }
    }

    public void run() {
        while (true) {
            ByteArrayOutputStream imageBytes = null;
            int parGalId = -1;
            String pictureUrl = null;
            Date date = null;
            synchronized (this) {
                if (parGalIdPool.size() != 0) {
                    parGalId = parGalIdPool.elementAt(0);
                    imageBytes = imageBytesPool.elementAt(0);
                    pictureUrl = pictureUrlPool.elementAt(0);
                    date = datePool.elementAt(0);
                } else {
                    try {                        
                        this.wait();                        
                        continue;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }


            try {
                if (date == null) {
                    Logger.log(ScaleImagesSaveToDbThread.class.getName(), "add to db picture... url = " + pictureUrl);
                    byte[] imageBytesData128 = scaleImage(imageBytes.toByteArray(), 120);
                    byte[] imageBytesData176 = scaleImage(imageBytes.toByteArray(), 168);
                    byte[] imageBytesData240 = scaleImage(imageBytes.toByteArray(), 232);
                    byte[] imageBytesData352 = scaleImage(imageBytes.toByteArray(), 344);

                    DatabaseActionManager.addPicture(parGalId, pictureUrl, imageBytesData128, imageBytesData176,
                            imageBytesData240, imageBytesData352);
                } else {
                    Logger.log(ScaleImagesSaveToDbThread.class.getName(), "add to db gallery's icon...url = " + pictureUrl);
                    byte[] imageBytesData128 = scaleImage(imageBytes.toByteArray(), 42);
                    byte[] imageBytesData176 = scaleImage(imageBytes.toByteArray(), 58);
                    byte[] imageBytesData240 = scaleImage(imageBytes.toByteArray(), 80);
                    byte[] imageBytesData352 = scaleImage(imageBytes.toByteArray(), 117);
                    DatabaseActionManager.updateSubGallery(pictureUrl, imageBytesData128, imageBytesData176,
                            imageBytesData240, imageBytesData352);
                }
            } catch (DatabaseConnectionException e) {
                Logger.logError(RefreshDBThread.class.getName(), e.getMessage(), e);
            } catch (ImageFormatterException ife) {
                Logger.logError(RefreshDBThread.class.getName(), ife.getMessage(), ife);
            }

            synchronized (this) {
                Logger.log(ScaleImagesSaveToDbThread.class.getName(), "removing from vector...");
                parGalIdPool.remove(0);
                imageBytesPool.remove(0);
                pictureUrlPool.remove(0);
                datePool.remove(0);
            }

            if (parGalIdPool.size() < 6) {
                Logger.log(ScaleImagesSaveToDbThread.class.getName(), "!!!try to notify monitor");
                synchronized (monitor) {
                    monitor.notify();
                }
            }
        }
    }

У мну уже просто голова не варит, но на мой взгляд вроде как логически не должно дедлока случиться, но может я сильно ошибаюсь...
Помогите плиз советом

Добавлено через 3 минуты и 44 секунды
Да, класс этот - это синглтон, запускается при старте приложения. Из потока, в котором скачивается картинка с http, вызывается метод addPictureData()

Автор: LSD 23.1.2008, 12:32
А вы какую JDK используете?

Добавлено через 1 минуту и 36 секунд
И можно на JVM где все это дело крутится жмякнуть Ctrl+Break?

Автор: Platon 23.1.2008, 12:41
Жестко сделано, меня когда учили работать с потоками, настоятельно рекомендовали избавляться от вложенных synchronized блоков. Я думаю, код имеет склонность впасть в DL.

Автор: W0LF 23.1.2008, 12:50
Дело в том, что оно не особо крутиться, я расчитываю на пятую джаву, то есть не расчитываю на самостоятельный выход из wait() потока

Добавлено через 18 секунд
хотя надо наверно просто это все переделать smile

Автор: LSD 23.1.2008, 13:07
Ну раз ты используешь JDK 1.5, то выброси ты все эти синхронизации и используй ArrayBlockingQueue, она не требует синхронизации и может останавливать поток, до тех пор пока в очереди не освободится место.

Автор: W0LF 23.1.2008, 13:51
о, спасибо. посмотрю че эт такое. но уже переделал smile теперь там ток один монитор

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)