Не следует блокировать потоки блоков классов из всех экземпляров классов - PullRequest
1 голос
/ 16 июня 2011
public class Fern extends Thread
{
    private String x = "varun"; 

    public void run()
    {
         synchronized(Fern.class){

        System.out.println(x);
        try {
            sleep(5);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        x = "Anku";
        }
    }
    public static void main(String args[]) throws Exception 
    {
        Fern f = new Fern();
        Thread t1 = new Thread(new Fern());
        Thread t2 = new Thread(new Fern());
        t1.start();
        t2.start();
    }
}

Вывод: varun varun

Поскольку блок был синхронизирован в Fern.class, только одному потоку разрешается входить в блок одновременно, независимо от того, к какому экземпляру он принадлежиттолько один замок для класса для всех экземпляров.Если я заменю новый Fern () в конструкторе Thread на один объект Fern, то получится: varun Anku.Поведение - это то, что было бы, если бы я синхронизировался (это).Я не понимаю, почему это происходит, так как я синхронизировал

Ответы [ 5 ]

3 голосов
/ 16 июня 2011

x не является переменной static.Измените его на static.

static String x = "varun";


EDIT : или передайте тот же объект в качестве параметра для t1 и t2.

Fern f = new Fern();
Thread t1 = new Thread(f); // pass the same object
Thread t2 = new Thread(f);
2 голосов
/ 16 июня 2011

x в каждом экземпляре потока отличается. Попробуйте private static String x использовать общий x в обоих случаях.

2 голосов
/ 16 июня 2011

x является переменной экземпляра - другими словами, хотя только один поток может войти в этот блок за раз, они смотрят на разные переменные.Изменение значения x в первом потоке не влияет на x, который просматривает второй поток.

Другими словами, синхронизация "правильная" (если вы не хотитеболее одного потока для ввода этого блока независимо * от экземпляра , но ваш доступ к данным не делает то, что вы думаете.

В качестве примечания, я лично предпочитаю блокировать ссылки, которые только мой класс может видеть.

Поскольку еще одно примечание , было бы лучше, если бы Fern реализовал Runnable вместо расширения Thread - выв настоящее время передает один поток другому конструктору, что не имеет особого смысла ...

1 голос
/ 16 июня 2011

Это не имеет ничего общего с синхронизацией.x является переменной экземпляра, поэтому каждый экземпляр Fern имеет свою собственную копию, инициализируется как «varun», затем печатается, затем устанавливается «Anku».

0 голосов
/ 16 июня 2011

Поскольку у вас есть два разных экземпляра Fern, тот факт, что один из них изменяет значение своего поля x, не виден другим. (Полагаю, поскольку вы не даете декларацию x. Чтобы получить лучшие ответы, отправьте только полный код.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...