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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопросы по многопоточности 
:(
    Опции темы
Alexey91
Дата 29.7.2013, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Здравствуйте!

Код

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created with IntelliJ IDEA.
 * User: Admin
 * Date: 26.07.13
 * Time: 20:18
 * To change this template use File | Settings | File Templates.
 */

public class Main {

    static {
        resultChangeLock = new ReentrantLock();
        result = 0;
        b = true;
    }

    private static void mod() {
        int value;

        //    resultChangeLock.lock();

        if (b = !b) {
            value = 1;
        } else value = -1;

        result = result + value;
        System.out.println("poly.mod : result = " + result);

        //    resultChangeLock.unlock();
    }

    public static void main(String args[]) {

        int NUM_OF_THREADS = 1000;

        while ((--NUM_OF_THREADS) >= 0) {

            new Thread(new Runnable() {

                @Override
                public void run() {
                    Main.mod();
                }
            }
            ).start();
        }
    }

    static private Lock resultChangeLock;
    static private boolean b;
    static int result;

}



В данном коде создается 1000 нитей, задача каждой из которых изменять значение статической переменной result.
Значение переменной result изменяется на единицу в зависимости от булевого значения переменной b. Переменная b также одна на весь класс.

Я не понимаю, почему если я запускаю этот код не используя ReentrantLock, то конечное значение переменной отлично от нуля?



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


Leprechaun Software Developer
****


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

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



Потому что b = !b и result = result + value; не атомарны.


--------------------
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   Вверх
Alexey91
Дата 29.7.2013, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



LSD, а можно подробнее?
Если не хотите отвечать, так скажите где про это почитать.
PM   Вверх
LSD
Дата 29.7.2013, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


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

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



Код

b = !b

тут на самом деле скрыто 3 операции: чтение значения b, лгическое отрицание, запись результата.
Предположим есть два потока p1 и p2, возможет такой сценарий:
- p1 читает значение true из переменной
- p1 инвертирует true на false
- p2 читает значение true из переменной
- p2 инвертирует true на false
- p1 записывает в b - false
- p2 записывает в b - false
итого мы дважды записали в b - false (и выполнили соответсвующую ветку if), хотя должны были записать один раз false и один раз true.

Аналогично и с
Код

result = result + value;



--------------------
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   Вверх
Alexey91
Дата 25.8.2013, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Возник вопрос.

Не страшно ли использовать два synchronized блока

То есть поток захватывает два объекта:

synchronized(X)
{
 synchronized(Y)
 {
 }
}

Я запутался. Мне говорят, что так делать нельзя, а я сделал тестовый код:

Код

/**
 * Created with IntelliJ IDEA.
 * User: Admin
 * Date: 25.08.13
 * Time: 18:40
 * To change this template use File | Settings | File Templates.
 */
public class Main extends Thread {

    static Integer x = 3;
    static Integer y = 3;


    public void f() throws InterruptedException {
        synchronized (x) {
            synchronized (y) {
                System.out.println("a");

            }
        }
    }

    public void run() {
        try {
            f();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) throws InterruptedException {

        Main m = new Main();
        m.start();

        synchronized (y)
        {
            System.out.println("I have captured");
            Thread.sleep(10000);
        }

        System.out.println("x = " + x + " y = " + y);

    }

}



И все работает. В документации ответ не нашел.


PM   Вверх
Stolzen
Дата 25.8.2013, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1041
Регистрация: 17.10.2005

Репутация: 23
Всего: 48



Цитата(Alexey91 @  25.8.2013,  16:14 Найти цитируемый пост)

Не страшно ли использовать два synchronized блока

Может быть страшно, если где-то в другом месте вы используете 

Код

synchronized(Y) {
 synchronized(X) {
 }
}


Тогда вероятность возникновения дедлока высокая. 


--------------------
datatalks.ru - анализ данных, статистика, машинное обучение
PM MAIL WWW   Вверх
Alexey91
Дата 25.8.2013, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Я понял!
Это похоже на то, что в документации про Deadlock было написано про двух парней кланящихся друг другу...

но в моем коде два раза будет встречаться

synchronized(x), synchronized(y)
PM   Вверх
Alexey91
Дата 25.8.2013, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



А если так

Код

synchronized(A)
{
 synchronized(A)
}




Вернее у меня в методе происходит есть sync-блок. И в этом методе я вызываю другой метод, который также используют sync-блок для этого объекта:
Код


void g()
{
 ... do some work ...
 synchronized(A)
 {
  .. do some work....
 }
}

void f()
{

synchronized(A)
{
 .... do some work ...
 g()
}


}

Это сообщение отредактировал(а) Alexey91 - 25.8.2013, 15:52
PM   Вверх
LSD
Дата 27.8.2013, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


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

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



Цитата(Alexey91 @  25.8.2013,  16:46 Найти цитируемый пост)
А если так

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


--------------------
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   Вверх
Alexey91
Дата 27.8.2013, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Решаю следующую задачу:

Существует массив элементов, который неупорядочен.
Задача в том, чтобы выводить на консоль элементы массива по порядку, непрерывно, начиная с первого элемента (1,2,3,4,5,6,7)
Элементы в массив могут добавляться во время упорядочивания элементов бесконечно. Поэтому он не является статическим. 

Если вы уже успели обработать 30 элементов массива 1,...,30, то новый добавляемый элемент не обязательно будет иметь значение 31. 
Он может иметь значение, например, 47. И тогда мы будем вынуждены ждать элемент со значением 31.
То есть добавляемое значение идет из генератора случайных чисел. Но все элементы массива уникальные.

Для решения задачи я сделал разделяемый объект, который хранит значение текущего элемента, которое нужно вывести на экран. С самого начала работы он равен 1
И из главного потока записал в локальные массивы N / (T - число потоков) элементов.
В свою очередь в цикле каждой нити происходит проверка на то, что элемент из массива 
нити равен значению разделяемого объекта, и если да, то значение из массива выводится на экран, и значение разделяемого объекта увеличивается на единицу.


Можно ли как-то организовать этот процесс быстрее?
Потому что разделения обработки на потоки выигрыша не вижу. Примерно одно время выполнения, что при одной, что при десяти нитях.
PM   Вверх
Mirkes
Дата 28.8.2013, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 7
Всего: 17



Попробуйте четко сформулировать задачу. Честно говоря ничего не понял.
Есть массив или последовательность, генерируемая на лету?
Массив надо отсортировать, или просто вывести на консоль подряд все натуральные числа которые обладают следующими свойствами:
1. Число N присутствует в уже полученной части последовательности
2. Все натуральные числа меньшие N уже выводились на печать.

Хотя не понимаю целей. Если все генерируемые числа принадлежат диапазону от 1 до M, то рано или поздно будут выведены все числа из этого диапазона.

На самом деле, сформулируйте задачу.


--------------------
Mirkes
PM MAIL   Вверх
LSD
Дата 28.8.2013, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


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

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



Присоеденюсь к Mirkes, из этой формулировки ничего непонятно.


--------------------
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   Вверх
Alexey91
Дата 28.8.2013, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



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

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

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


 




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


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

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