[CareerCup] 16.6 Synchronized Method 同步方法

Grandyang發表於2016-04-17

 

16.6 You are given a class with synchronized method A and a normal method B. If you have two threads in one instance of a program, can they both execute A at the same time? Can they execute A and B at the same time? 

 

當我們給一個方法加了synchronized關鍵字,我們確保了兩個執行緒不能同時執行同一個物件的該方法。所以對於第一問的答案是根據情況而定,如果兩個執行緒有物件的同一個例項,那麼答案是不行,它們不能同時執行方法A,但是當它們有物件的不同例項,那麼它們就可以。我們可以用鎖的概念來理解,一個synchronized方法就是在該例項物件上加了鎖的方法,這樣就阻止了其他執行緒執行該例項的其他synchronized方法。

對於第二部分,由於方法B並沒有synchronized關鍵字,所以當執行緒2執行方法B時不會有東西阻礙執行緒1執行方法A,而且不論執行緒1和2是否有相同的例項物件。總而言之,需要牢記的是,只有一個同步synchronized方法可以在物件中的一個例項中執行,其他執行緒可以執行該例項的非同步non-synchronized方法,或者他們可以執行該物件的其他例項的任何方法。

 

public class Foo {
    private String name;
    
    public Foo(String nm) {
        name = nm;
    }
    
    public String getName() {
        return name;
    }
    
    public void pause() {
        try {
            Thread.sleep(1000 * 3);
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public synchronized void methodA (String threadName) {
        System.out.println("thread" + threadName + " starting; " + name + ".methodA()");
        pause();
        System.out.println("thread" + threadName + " ending: " + name + ".methodA()");
    }
    
    public void methodB(String threadName) {
        System.out.println("thread " + threadName + " starting: " + name + ".methodB()");
        pause();
        System.out.println("thread " + threadName + " ending: " + name + ".methodB()");
    }
}

public class MyThread extends Thread {
    private Foo foo;
    public String name;
    public String firstMethod;
    public MyThread(Foo f, String nm, String fM) {
        foo = f;
        name = nm;
        firstMethod = fM;
    }
    
    public void run() {
        if (firstMethod.equals("A")) {
            foo.methodA(name);
        } else {
            foo.methodB(name);
        }
    }
}

public class j {
    public static void main(String[] args) {
        System.out.println("Part 1 Demo with same instance.");
        Foo fooA = new Foo("ObjectOne");
        MyThread thread1a = new MyThread(fooA, "Dog", "A");
        MyThread thread2a = new MyThread(fooA, "Cat", "A");
        thread1a.start();
        thread2a.start();
        while (thread1a.isAlive() || thread2a.isAlive()) {}
        System.out.println("\n\n");
        
        System.out.println("Part 1 Demo with different instance.");
        Foo fooB1 = new Foo("ObjectOne");
        Foo fooB2 = new Foo("ObejctTwo");
        MyThread thread1b = new MyThread(fooB1, "Dog", "A");
        MyThread thread2b = new MyThread(fooB1, "Cat", "A");
        thread1b.start();
        thread2b.start();
        while (thread1b.isAlive() || thread2b.isAlive()) {};
        System.out.println("\n\n");
        
        System.out.println("Part 2 Demo.");
        Foo fooC = new Foo("ObjectOne");
        MyThread thread1c = new MyThread(fooC, "Dog", "A");
        MyThread thread2c = new MyThread(fooC, "Cat", "B");
        thread1c.start();
        thread2c.start();
    }
}

 

CareerCup All in One 題目彙總

相關文章