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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Потоки и блокировка, хочу уточнить 
:(
    Опции темы
nucer
Дата 1.7.2004, 00:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 118
Регистрация: 21.6.2004
Где: Москва

Репутация: -1
Всего: 0



Есть например такой класс
Код
class My extends Thread
{
public Socket socket; // Определяется в другом месте

public void some sendData ( ... )
{
 synchronized ( this )
 {
  // Отправка данных через socket
 }
}
}
Так вот, смогут ли другие методы других объектов что-нибудь отправить в это время через этот socket? Если да, то как надо делать?

Это сообщение отредактировал(а) nucer - 1.7.2004, 00:42
PM MAIL   Вверх
Domestic Cat
Дата 1.7.2004, 01:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172



Смогут. Сделаuте что-нибудь вроде:

Код

class SomeClass
{
     public static final boolean SOCKET_IS_USED = true;
     public static final boolean SOCKET_IS_NOT_USED = false;

     private Socket socket;
     private boolean isSocketInUse = SOCKET_IS_NOT_USED;      
   
     public synchronized Socket getSocket()
     {
            while (isSocketInUse)
            {
                  wait();
            }
            isSocketInUse = SOCKET_IS_USED;
            return socket;
     }

     public synchronized void releaseSocket()
     {
           isSocketInUse = SOCKET_IS_NOT_USED;
           notify();
     }

     // dalee idet otkrytie soketa, inicializacija, itp
}



--------------------

PM   Вверх
Sardar
Дата 1.7.2004, 01:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 4
Всего: 317



Это механизм семафоров, лучше вынести в отдельный клас. Механизм синхронизации не до конца освоил, но по моему синхронизацию надо брать от socket: synchronized(socket);


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Domestic Cat
Дата 1.7.2004, 01:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172



Собственно, у кого забирать лок, разницы особоu нет. Посмотрите фак:

http://forum.vingrad.ru/index.php?showtopic=24781


--------------------

PM   Вверх
nucer
Дата 1.7.2004, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 118
Регистрация: 21.6.2004
Где: Москва

Репутация: -1
Всего: 0



А если synchronized ( this.socket ) тогда не смогут? И что будет, если в один и тот же сокет одновременно начнут записывать два потока?
PM MAIL   Вверх
Domestic Cat
Дата 1.7.2004, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172





Перечитал первыu ваш пост и понял что вчера я его недопонял smile.gif

Другие потоки смогут работать с этим сокетом если получат на него ссылку. Если нужно чтобы в сокет писал только один поток в данныu момент, то приведенныж вами код работать будет, при условии что другие потоки не получают этот сокет, скажем my.socket . Можно сделать socket приватным и тогда вы будете уверены что ничего плохого не произоuдет.

Цитата
И что будет, если в один и тот же сокет одновременно начнут записывать два потока?


getOutputStream() возврашает output стрим данного сокета. Если несколько потоков одновременно попытаются получить этот стрим и писать в него, то по-моему ничего хорошего не получится.


--------------------

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


Шустрый
*


Профиль
Группа: Участник
Сообщений: 118
Регистрация: 21.6.2004
Где: Москва

Репутация: -1
Всего: 0



Приватным я его сделать не могу и как раз по ссылке socket и передаётся. Вообще у меня есть класс Server, есть класс Client, для каждого клиента есть свой сокет и не от него зависит что и когда другие клиенты будут ему посылать через этот сокет. И я не пойму, этот synchronized вообще как-нибудь работает?
PM MAIL   Вверх
Domestic Cat
Дата 1.7.2004, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172



Погодите, я не понял, речь идет о сервере? Тогда вроде вы используете ServerSocket, в бесконечном цикле опрашиваете его while(true) { clientSocket = serverSocket.accept(); } и облуживаете клиента на сокете которыu открывается для каждого клиента своu причем автоматически.

Если хотите могу запостить код из книжки Java 2 Network Protocols - там есть пример сервера используюшеgо пул потоков для одновременнож работы с многими клиентами.

Тем не менее, RMI проше smile.gif


--------------------

PM   Вверх
nucer
Дата 2.7.2004, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 118
Регистрация: 21.6.2004
Где: Москва

Репутация: -1
Всего: 0



Да я так и делаю. Для каждого клиента создаётся отдельный поток, и потом клиенты посылают друг другу всякие данные. Т.е. один клиент обращается к сокету другого...
PM MAIL   Вверх
Domestic Cat
Дата 2.7.2004, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172



Все равно мне не понятно. Может вы бу поподробнее написали?


--------------------

PM   Вверх
LSD
Дата 2.7.2004, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Есть еще вариант с классом ThreadLocal, который позволяет иметь отдельную переменную для каждого потока и не использовать синхронизацию, может это вам поможет.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
nucer
Дата 3.7.2004, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 118
Регистрация: 21.6.2004
Где: Москва

Репутация: -1
Всего: 0



Вот это Server:
Код
public class Server
{
protected ServerSocket server;

public Server ( int port )
{
 Socket temp;
 User t_us;
 User.clients = new LinkedList ();
 try
 {
  this.server = new ServerSocket( port );
  while ( true )
  {
   User.clients.addLast( new User( this.server.accept () ) );
  }
 }
 catch ( IOException e )
 {
  System.out.println( "Error: " + e );
 }
}

static public void main ( String[] args )
{
 System.out.println( "Working..." );
 Server my = new Server( 1300 );
}
}

Вот кусок класса User:
Код
public class User extends Thread
{
public static LinkedList clients;
...
public User( Socket so )
{
 this.socket = so;
 try
 {
  Class.forName( "com.mysql.jdbc.Driver" );
  this.con = DriverManager.getConnection( "jdbc:mysql://localhost/bd?user=login&password=123123" );
 }
 catch ( SQLException e )
 {
  System.out.println( "1 " + e );
 }
 catch ( ClassNotFoundException e )
 {
  System.out.println( "2 " + e );
 }
 this.addr = this.socket.getInetAddress ();
 this.setPriority( 2 );
 this.start ();
}
public void run ()
{
 this.running = true;
 this.receiveMessages ();
}
protected void receiveMessages ()
{
 int t = -99;
 StringBuffer dat;
 try
 {
  while ( this.running && t != -1 )
  {
   if ( this.socket.isClosed () )
   {
    dat = null;
   }
   dat = new StringBuffer ();
   BufferedReader input = new BufferedReader( new InputStreamReader( this.socket.getInputStream () ) );
   t = input.read ();
   while ( t != 0x00 && t != -1 )
   {
    if (t >= 0 && t < 65536 )
    {
     dat.append( (char)t );
    }
    t = input.read ();
   }
   
   if ( t == -1 )
   {
    this.endThread ();
    dat = null;
   }
   
   if ( dat != null )
   {
    this.workMessage( dat.toString() );
   }
  }
 }
 catch ( IOException e )
 {
  System.out.println( "3 " + e );
 }
}
protected void workMessage ( String mes )
{
 // Обработка полученного сообщения и, в зависимости от него, рассылка данных остальным клиентам
}
}

Вроде так. Если ещё подробнее, то надо весь исходник выкладывать. Я думаю ни у кого не будет желания разбираться с ним.
PM MAIL   Вверх
LSD
Дата 3.7.2004, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Я так понял вашу проблему: необходимо чтобы клиент захватывал блокировку на сокет и работал с ним монопольно, а остальные в этот момент ждали. Если так то вы правильно предпологали.
Код
synchronized(socket)// поток который дойдет до этого кода первым захватит блокировку, а все остальные встанут
{
 //здесь он монопольно работает с сокетом
}//блокировка освобождается и следующий поток может ее захватить

С одним сокетом может работать только один клиент одновременно, но если сокетов несколько а все равно надо всех синхронизировать, то надо использовать единый объект наподобии TreeLock в AWT.
Код
public static final Object LOCK = new Object();
synchronized(LOCK)
{
 //здесь единовременно работает только один поток
}



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
nucer
Дата 3.7.2004, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 118
Регистрация: 21.6.2004
Где: Москва

Репутация: -1
Всего: 0



Да мне нужно первое их того, что вы сказали. Значит так и буду делать. Спасибо всем за участие biggrin.gif
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

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

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


 




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


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

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