2016-03-07 4 views
1

Я пытаюсь реализовать синхронизацию, используя следующий код, но не работает должным образом.Нити синхронизации не работают

class Callme extends Thread{ 

    synchronized void call() { 

    System.out.print("[" + "Hello"); 

    try { 

    Thread.sleep(1000); 

    } catch(InterruptedException e) { 

    System.out.println("Interrupted"); 
    } 

    System.out.println("]"); 

    } 


    public void run() 
    { 
    call(); 
    } 

} 


public class Threads { 

    static void main(String args[]) { 

    Callme target = new Callme(); 

    Callme target2 = new Callme(); 

    target.start(); 

    target2.start(); 
}} 

Выход должен быть [Hello] [Hello], но это что-то вроде [Hello [Hello]], который не синхронизирован.

+0

Добавить 'static' перед' synchronized void call() {'. – saka1029

+0

Зачем должен выводиться '[Hello] [Hello]'? Независимо от того, какие рассуждения привели вас к этому ожиданию, это проблема. –

+0

@DavidSchwartz Поскольку вызов() является синхронизированным методом, а другой поток «target2» не может получить к нему доступ, пока текущий поток «target1» не обратится к методу call(). – toadalskiii

ответ

3

Вы код работает отлично IMO и на самом деле это не проблема синхронизации там,

Почему не ?:

Каждый объект класса поток вызывает свой собственный метод call и печать когда он должен, они на самом деле пытаются получить один и тот же ресурс (System.out.print), но это не синхронизируется .... так что это абсолютно правильное поведение, которое вы получаете примерно как

[Hello [Hello]]

у вас выход.

+0

Как создать два потока, используя один объект, и вызвать метод call() для вывода [Hello] [Hell]. – toadalskiii

+0

На самом деле, System.out.println() _is_ synchronized, что объясняет, почему программа никогда не выводит ничего подобного '[He [lHleollo]]'. Но только потому, что программа вызывает 'synchronized' методы, не означает, что сама программа будет потокобезопасной. Синхронизация должна происходить на правильном уровне. –

1

Хорошо, что ответы на вопросы приходят вам на помощь. Но я думаю, что это лучше, если вы можете понять основную концепцию синхронизации потоков. Поэтому, когда вы синхронизируете метод, подобный тому, что вы делали выше, это означает, что конкретному потоку, который хочет выполнить конкретный синхронизированный метод, требуется блокировка объекта. Поэтому, как только блокировка объекта была взята из другого потока, конкретному потоку придется ждать, пока первый поток не освободит блокировку объекта.

Но здесь вы используете два отдельных потока и два отдельных объекта. так что очевидно, что вы получаете правильно.

0

Результат должен быть [Hello [Hello]]. Из-за вас новые два потока, цель, target2 и call() - это метод членов класса Callme .so target и target2 используют свой собственный вызов (). если вы хотите синхронизировать поток, вам нужно сделать цель и target2 вызывать тот же метод call().

, например:

enter code here 

общественный класс Callme расширяет темы {

public void run() 

    { 

    Threads.call(); 
    } 

}

Темы общественного класса {

synchronized static void call() { 

    System.out.print("[" + "Hello"); 

    try { 

    Thread.sleep(1000); 

    } catch(InterruptedException e) { 

    System.out.println("Interrupted"); 
    } 

    System.out.println("]"); 

    } 
public static void main(String args[]) { 

    Callme target = new Callme(); 

    Callme target2 = new Callme(); 

    target.start(); 
    target2.start(); 
    } 

}

Смежные вопросы