2017-02-08 2 views
2

wurde ich interviewt und ich wurde nach einer Klasse mit zwei Funktionen m1() und m2() gefragt. m1() ist synchronisiert und m2() ist nicht und zwei Threads t1 und t2 versuchen auf dieses Objekt zuzugreifen. Wenn nun t1 auf die Funktion m1() zugreift, kann dann t2 auf die Methode m2() gleichzeitig zugreifen?Bezüglich der synchronisierten Funktion

Ich sagte ja sollte es erlaubt sein, darauf zugreifen, da es keine Sperre auf m2() -Methode gibt, aber der Interviewer bestand darauf, da das Schloss auf dem gleichen Objekt ist es nicht erlaubt, auf die m2 zuzugreifen() Funktion zu T2-Thread.

Dafür schrieb ich ein Programm zu überprüfen und festgestellt, dass alles, was ich sagte, richtig war. Bitte beachten Sie das Programm mit der Ausgabe.

class myExperiment2 implements Runnable{ 
    myThreadEx m; 

    myExperiment2(myThreadEx m){ 
     this.m = m; 
    } 

    @Override 
    public void run() { 
     try { 
      m.m2(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class myExperiment1 implements Runnable{ 
    myThreadEx m; 

    myExperiment1(myThreadEx m){ 
     this.m = m; 
    } 

    @Override 
    public void run() { 
     try { 
      m.m1(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class myThreadEx{ 

    synchronized void m1() throws InterruptedException { 
     System.out.println("1 am in m1....1"); 
     Thread.sleep(10000); 
     System.out.println("I am in m1()"); 
     Thread.sleep(10000); 
     System.out.println("1 am in m1....2"); 
    } 

    void m2() throws InterruptedException{ 
     System.out.println("1 am in m2....1"); 
     Thread.sleep(5000); 
     System.out.println("i am in m2()"); 
     Thread.sleep(5000); 
     System.out.println("1 am in m2....2"); 
    } 
} 

public class ThreadEx { 

    public static void main(String args[]){ 
     myThreadEx m = new myThreadEx(); 

     Thread t1 = new Thread(new myExperiment1(m)); 
     Thread t2 = new Thread(new myExperiment2(m)); 

     t1.start(); 
     t2.start(); 
    } 
} 

Der Ausgang ist

1 Uhr m1 .... 1
01.00 in m2 .... 1
i in m2 bin()
01.00 in m2 .... 2
ich bin in m1()
01.00 in m1 .... 2

Kann jemand su nimmst du mich, wenn ich etwas vermisse oder wenn es ein mögliches Szenario gibt, in dem ich falsch liegen kann und was auch immer das Interview gesagt hat, war das richtig?

+3

Wenn ich die Frage falsch verstanden haben, oder Sie haben nicht genau es im Zusammenhang, war der Interviewer falsch. –

+0

@AndyTurner http://meta.stackoverflow.com/questions/254990/when-should-code-formatting-be--used-for-non-code-text Oder versuchen Sie zu erklären, warum ___you___ denken, dass gedruckter Text Code ist. Ich würde das gerne wissen. – Tom

+1

@Tom Ausgabe von Programmen (und Dinge wie Stack-Traces) sind am besten in monospaced Schriftarten angezeigt, weil es Zeilenumbrüche und Leerzeichen für die Formatierung vorhanden ist. Und es sieht einfach schöner aus: Die unterschiedlichen Breiten der 1. Spalte vermischen sich mit der Lesbarkeit. Und so erscheint es in Ihrem Terminal, wenn Sie es ausführen (es sei denn, schaudern Sie, Sie verwenden keine monospaced Schriftart in Ihrem Terminal, die einfach doof ist). –

Antwort

1

Ich würde sagen, dass Interviewer falsch lag. Er wäre richtig gewesen, wenn sowohl m1 als auch m2 synchronisiert worden wären. Im Falle Ihrer Frage gab es keine Sperre, die mit m2 verknüpft ist, also nichts, was andere Threads daran hindert, sie auszuführen.

3

Wenn ich die Frage nicht missverstanden habe oder Sie sie nicht richtig miteinander verglichen haben, lag der Interviewer falsch.

Und natürlich, the semantics of synchronized methods gegeben:

synchronized void foo() { ... } 

ist

void foo() { synchronized (this) { ... } } 

(zumindest für eine Instanz-Methode)

Dann anderen Threads können immer "access" identisch der Methode zur gleichen Zeit (wie in mehreren Threads haben diese Methode in ihrem Stack-Trace); Sie werden sofort blockiert.

+1

Und hier kommt der Teil, wo Sie dem Interviewer erklären müssen, dass er falsch liegt. Einige sind offen für den Vorschlag, andere nicht. – AxelH

0

Interviewer nicht in Ordnung war, wenn er die folgende gemeint,

Es gibt zwei Arten Sperrstrategie Sie

  1. Objekt intrinsische Schloss (this wie in Ihrem Fall oder HashTable)
  2. Schließungs annehmen kann definiert unter

Schließungs,

public class PrivateLock { 
    private final Object myLock = new Object(); 
    @GuardedBy("myLock") Widget widget; 

    void someMethod() { 
     synchronized(myLock) { 
      // Access or modify the state of widget 
     } 
    } 
} 

also wenn jemand folgendes tut, die m2 wird dazu führen, nicht aufrufen,

//myThreadEx also shared by another class which does myThreadEx.m1 
synchronized(myThreadEx) { 
    myThreadEx.m2(); 
} 
+1

Sicher. Das habe ich behoben. – GauravJ

Verwandte Themen