2017-01-26 3 views
0

Я тестировал концепцию многопоточности с использованием этих трех классов.Java многопоточность Синхронизированный блок

Этот класс состоит из методов, выполняемых потоками.

class MainClass { 

static MainClass mainClass; 

String name = "Sibendu"; 

MainClass() 
{ 
    mainClass = this; 
} 

public static void main(String args[]) 
{ 
    new MainClass(); 
    ThreadImpl thread = new ThreadImpl(mainClass); 
    ThreadImpl2 thread2 = new ThreadImpl2(mainClass); 

    thread.start(); 
    thread2.start(); 
} 

public void printMyName() throws InterruptedException { 
    String name = "Sibendu"; 
    synchronized (name) { 
     System.out.println("Inside printMyName()"); 
     Thread.sleep(4000); 
     System.out.println(name); 
    } 
} 

public void printMyName2() throws InterruptedException { 

    synchronized (name) { 
     System.out.println("Inside printMyName2()"); 
     Thread.sleep(4000); 
     System.out.println(name); 
    } 
} 

} 

Два потока:

class ThreadImpl extends Thread { 

MainClass mainClass = null; 

ThreadImpl(MainClass mainClass) { 
    this.mainClass = mainClass; 
} 
@Override 
public void run() { 
    try { 
     mainClass.printMyName(); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    } 
    } 




public class ThreadImpl2 extends Thread 
{ 

MainClass mainClass = null; 
ThreadImpl2(MainClass mainClass) { 
    this.mainClass = mainClass; 
} 

@Override 
public void run() { 
    try { 
     mainClass.printMyName2(); 
    } catch (InterruptedException e) { 

     e.printStackTrace(); 
    } 
} 

} 

Блоки синхронизации находятся на двух различных переменных. Один из них является локальным, а другой - переменной экземпляра MainClass.

Мой вопрос, даже если синхронизация выполняется на двух разных типах переменных. Почему «thread2» помещается в состояние ожидания до тех пор, пока thread1 не завершит операцию?

Я проверил выход. Это выход:

Внутри printMyName() Sibendu Внутри printMyName2() Sibendu

ответ

3

Причина заключается в том, что вы синхронизировать строки литералов, которые на самом деле та же переменная: "Sibendu" == "Sibendu".

Поэтому, несмотря на видимость, вы используете только 1 замок.

String.intern() documentation говорит:

Все символьные строки и строковые константы выражения интернированы.

Если вы замените один из них на name = new String("Sibendu"), вы увидите, как вы ожидали.

+0

Итак, синхронизация происходит на строковой литературе, которая является «Sibendu»? – Sibendu

+2

Каждый объект является блокировкой в ​​java. Когда вы используете тот же самый объект, вы используете ту же самую блокировку. И на самом деле идентичные _String litals_ дают одни и те же объекты. Как следствие, я думаю, что очень сложно использовать 'String' как блокировки. – rom1v

+0

Истинный ... тестировал синхронизацию на «этом» из ниоткуда, пришло в голову попробовать этот кусок кода – Sibendu

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