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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сделать чтобы перем. была видна всем классам ? Область видимости переменных. 
:(
    Опции темы
Snik
Дата 25.8.2008, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Добрый день! Подскажите как сделать чтобы эта программка вывела последнее сообщение sum = 600.0

Код

//public double sum; Ну почему нельзя обьявить общедоступную переменную здесь ?
//                               как решить задачу ?

class Caller implements Runnable {
    double member;
    public double sum;

    public Caller(int n) {
        member = n;
        new Thread(this).start();
    }

    public void run() {
        double localSum = 0;

        for (int i = 100; i > 0; i--) {
            localSum += member;
        }
        sum = sum + localSum;
        System.out.println("sum = " + sum);
    }
}

public class Start {
    public static void main(String args[]) {
        for (int j = 1; j <= 3; j += 1) {
            new Caller(j);
        }

    }
}


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


Шустрый
*


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

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



если сделать вот такой код, то переменная sum в итоге станет = 600, но вот когда она распечатает это значение, - неизвестно. Код сделан так, что любой из потоков может сделать вывод даннх первым или 2-м или 3-м.
Код

package at.vingrad.tests;

class Caller implements Runnable {
    double member;
    public static Double sum = new Double(0);

    public Caller(int n) {
        member = n;
        new Thread(this).start();
    }

    public void run() {
        double localSum = 0;

        for (int i = 100; i > 0; i--) {
            localSum += member;
        }
        synchronized (sum) {
            sum = new Double(sum.doubleValue() + localSum);
        }
        System.out.println("sum = " + sum);
    }
}

public class Start {
    public static void main(String args[]) {
        for (int j = 1; j <= 3; j += 1) {
            new Caller(j);
        }

    }
}

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


Autonomous R&D
**


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

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



Цитата(alexadr @  25.8.2008,  14:18 Найти цитируемый пост)
Код

        synchronized (sum) {
            sum = new Double(sum.doubleValue() + localSum);
        }

Нехорошо smile
PM MAIL   Вверх
alexadr
Дата 25.8.2008, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(ivg @  25.8.2008,  12:15 Найти цитируемый пост)
Нехорошо  

аргументы?!
PM MAIL   Вверх
ivg
Дата 25.8.2008, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


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

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



Цитата(alexadr @  25.8.2008,  16:29 Найти цитируемый пост)
аргументы?!

Один поток держит монитор на одном объекте, другой поток входит в монитор на другом объекте - синхронизации, как таковой нет.
PM MAIL   Вверх
alexadr
Дата 25.8.2008, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



да вроде переменная то статик:
Код

public static Double sum = new Double(0);

поэтому все потоки работают с одним объектом
PM MAIL   Вверх
ivg
Дата 25.8.2008, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


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

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



Цитата(alexadr @  25.8.2008,  19:47 Найти цитируемый пост)
да вроде переменная то статик:
поэтому все потоки работают с одним объектом

 smile Тогда здесь:
Код

sum = new Double(sum.doubleValue() + localSum);
, что каждый раз один и тот же объект создаётся что ли?
Объектная переменная в Java - это, по сути, ссылка на объект, и синхронизация происходит не на ней, а именно на том объекте, на который она ссылается.
В качестве примера - предлагаю многократно позапускать такой код:
Код

public class Caller implements Runnable {

    double member;
    public static Double sum = new Double(0);

    public Caller(int n) {
        member = n;
    }

    public void run() {
        for (int i = 1000; i > 0; i--) {
            synchronized (sum) {
                sum = new Double(sum.doubleValue() + member);
            }
        }
    }

    public static void main(String args[]) throws InterruptedException {
        Thread[] threads = new Thread[10];
        for (int i = 0; i < threads.length; ++i) {
            threads[i] = new Thread(new Caller(i+1));
            threads[i].start();
        }
        for(Thread t : threads) {
            t.join();
        }
        System.out.println("sum = " + sum);
    }
}
, результаты будут отличаться.
PM MAIL   Вверх
alexadr
Дата 25.8.2008, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



эээ, да вот с этим согласен:
Код

sum = new Double(sum.doubleValue() + localSum);

прогнал че-то...
PM MAIL   Вверх
Snik
Дата 25.8.2008, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Обязательно применять метод synchronized если мне не важно какой из потоков изменит sum первым ?
PM MAIL   Вверх
Platon
Дата 25.8.2008, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



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

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

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


 




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


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

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