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


Автор: barin_Student 27.11.2007, 13:18
У меня есть довольно большой(неудобно на форуме смотреть) класс для примера , вот там синхронизация нужна , а как правильно ее выполнить не могу найти Faq , вот и у вас хотел бы спросить.(могу привести тот класс). Просто когда тупо везде втыкаю синхронизацию , поток останавливается без ошибок , просто висит и все. smile 

Автор: barin_Student 27.11.2007, 13:37
вот кусок класса внутри которого устраиваивается синхронизация , вот если убрать закаментирование то получается так что просто класс повисает.
Классы требуещие синхронизации есть демоны.
Код

 case Data.SUBMIT_SM :
                            try
                            {
                                                            SubmitSM submit = new SubmitSM();
                                                            submit.setData(request.getData());
                                                                                            
                                                            String telefon=submit.getDestAddr().getAddress();
                                                            System.out.println("Phone # "+telefon.substring(1, 4));
                                                            history.Write("Submit for number ["+telefon+"]");
                                                            boolean isOurNumber=false;
                                                            SubmitSMResp submitResponse = (SubmitSMResp) response;
                                                            submitResponse.setMessageId(assignMessageId());
               
                                                            if((telefon.substring(1, 4).equals(BeelineNumber1))||
                                                                 (telefon.substring(1, 4).equals(BeelineNumber2))||
                                                                 (telefon.substring(1, 4).equals(KCellNumber1))||
                                                                 (telefon.substring(1, 4).equals(KCellNumber2)))
                                                            {
                                                                isOurNumber=true;
                                                                System.out.println("Ura , ELKI PALKI");
                                                            }
                                                            System.out.println("BeelineNumber1: "+BeelineNumber1);
                                                            System.out.println("BeelineNumber2: "+BeelineNumber2);
                                                            System.out.println("KCellNumber1: "+KCellNumber1);
                                                            System.out.println("KCellNumber2: "+KCellNumber2);
                                                            if((telefon.substring(1, 4).equals(BeelineNumber1))||
                                                                 (telefon.substring(1, 4).equals(BeelineNumber2)))
                                                            {
                                                                history.Write("Submit for Beeline "+submit.debugString());
                                                                submit.setDestAddr(Beeline_ton,Beeline_npi,telefon);
                                                                //synchronized(this.SyncBeeline)
                                                                {
                                                                    history.Write("Submit for Beeline "+submit.debugString());
                                                                    this.SyncBeeline.flagIncommingPDU=true;
                                                                    this.SyncBeeline.setPDU(submit);
                                                                }
                                                            }                                                                   
                                      
                                                            if (telefon.substring(1, 4).equals(KCellNumber1)||(telefon.substring(1,4).equals(KCellNumber2)))
                                                            {
                                                                 submit.setDestAddr(KCell_ton,KCell_npi,telefon);
                                                                // synchronized(this.SyncKCell)
                                                                 {
                                                                    this.SyncKCell.flagIncommingPDU=true;
                                                                    this.SyncKCell.setPDU(submit);
                                                                 }
                                                             }
                                                           
                                                             if(isOurNumber == false)
                                                             {
                                                                response.setCommandStatus(0x00000045);
                                                                history.Write("Error Submit no number in our config file "+telefon);
                                                                history.Write("Send response to OpenWay with Error "+submitResponse.debugString());
                                                             }
                                  display("putting message into message store");        
                                 messageStore.submit((SubmitSM) request, submitResponse.getMessageId(), systemId);
                                byte registeredDelivery =(byte) (((SubmitSM) request).getRegisteredDelivery() & Data.SM_SMSC_RECEIPT_MASK);
                                if (registeredDelivery == Data.SM_SMSC_RECEIPT_REQUESTED) {
                                    deliveryInfoSender.submit(this, (SubmitSM) request, submitResponse.getMessageId());
                                }
                            }catch (Exception e)
                            {
                                System.out.println("ERROR "+e);
                                                                errorWriter.WriteError("error in SubmitSM "+e);
                            }
                            break;

Автор: ivg 27.11.2007, 20:07
Цитата(barin_Student)
Нехорошо блин!!!

Точно.
this.SyncBeeline - класс этого объекта наледует Thread? Если так, то предположу, что вы пытаетесь реализовать асинхронную посылку SMS?
Вобщем, по тому коду, что вы привели, ничего сказать нельзя, только предположения. Покажите код класса объекта this.SyncBeeline, особенно где есть 
synchronized(this) или this.wait()
Если это потоки, покажите основной метод, в котором они работают (обычно run()).

PS: В одиночку трудитесь? Ваш код надо улучшать... 

Автор: barin_Student 28.11.2007, 14:16
Делаю один и заканчиваю , для поключения к SMSC использую синхронную часть , а мой SMSC работает асинхронно(так надо), синхронизация требовалась , для того чтоб не преравать к примеру получения ответа на запрос , потем отправления другого запроса(дожадаться окончания действия), решил все без синхронизации , чуть флаги изменил и все.
Насчет кода , да знаю есть куча клякс и требует оптимизации. Со временем прийду к полному пониманию язака ява. А то я его уже месяца 4 изучаю , а чтоб  написать  и точно знать как что сейчас пойдет , вот к этому я еще не пришел.  smile 

Автор: Dims 28.11.2007, 19:22
synchronized ждёт, пока объект-аргумент освободится, потом захватывает его и проходит дальше. пока объект захвачен, другие потоки ждут у входа своих synchronized.

То есть, synchronized должен огораживать использование того объекта, который нельзя использовать параллельно. Это не обязательно тот объект, который захватывается и освобождается. Он может служить лишь "светофором" и ограничивать "езду" по другому объекту -- "перекрёстку".

Если synchronized стоит перед методом, то захватывается весь объект, к которому принадлежит этот метод.

Если у Вас всё зависает, значит образовалась "пробка". Например, несколько потоков ждут освобождения каких-то объектов, которые не могут быть освобождены, так как отвечающие за это потоки тоже ждут.

Старайтесь использовать как можно меньше объектов синхронизации.

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