0
public class Common {      
    public synchronized void synchronizedMethod1() {
        System.out.println("synchronizedMethod1 called");
        try {
            Thread.sleep(1000);
            } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("synchronizedMethod1 done");
    }
    public void method1() {
        System.out.println("Method 1 called");
        try {
            Thread.sleep(1000);
            } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Method 1 done");
    }
}



public class MyThread extends Thread {
    private int id = 0;
    private Common common;

    public MyThread(String name, int no, Common object) {
        super(name);
        common = object;
        id = no;
    }

    public void run() {
        System.out.println("Running Thread" + this.getName());
        try {
            if (id == 0) {
                common.synchronizedMethod1();
                } else {
                common.method1();
            }
            } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Common c = new Common();
        MyThread t1 = new MyThread("MyThread-1", 0, c);
        MyThread t2 = new MyThread("MyThread-2", 1, c);
        t1.start();
        t2.start();
    }
}

出力:

Running ThreadMyThread-1  
synchronizedMethod1 called  
Running ThreadMyThread-2  
Method 1 called  
synchronizedMethod1 done  
Method 1 done  

synchronizedMethod1 を呼び出したときに method1() が実行されないようにする方法を見つけたいと思います。私が間違っていない限り、同期されているかどうかに関係なく、すべてのメソッドが呼び出され、Java は実行中および実行前にそれらをコンパイルします。

代わりに Lock オブジェクトを使用したり、method1() を同期メソッドにしないでください。

4

2 に答える 2

1

synchronizedMethod1 を呼び出したときに method1() が実行されないようにする方法を見つけたい

これを行う最も簡単な方法は、method1()も にすることsynchronizedです。Commonこれは、両方のメソッドが呼び出しているインスタンスをロックすることを意味します。synchronizedMethod1()またはを呼び出すことができるスレッドは 1 つだけmethod1()です。

私が間違っていない限り、同期されているかどうかに関係なく、すべてのメソッドが呼び出され、Java は実行中および実行前にそれらをコンパイルします。

この質問がわかりません。JVM のコンパイルまたは最適化フェーズについて心配する必要はありません。

代わりに Lock オブジェクトを使用する必要がありましたか?

通常、メソッドを作成することは、ロック オブジェクトsynchronizedを使用することほど良くないと考えられています。private finalロック オブジェクトを使用すると、ロックをより細かく設定できます。たとえば、メソッドのロックでは、保護を必要としないログ メッセージやその他のステートメントsynchronizedも同様です。ただし、メソッド全体をロックすることが目的の場合は、メソッドを同期しても問題ありません。

于 2012-07-18T20:10:14.997 に答える
0

相互に排他的である必要がある場合は、同じロックでそれらを保護する必要がありmethod1ます。synchronizedMethod1これが を使用しているLockか、単にsynchronize同じ Object インスタンスを呼び出しているかに関係なく、結果はほぼ同じです。

複数のスレッドの実行を許可したいが、 が呼び出されmethod1たときは許可したくない場合は、それを実現するために が必要です。synchronizedMethod1ReadWriteLock

public class Common {     
    ReadWriteLock rwLock = new ReentrantReadWriteLock();

    public void synchronizedMethod1() {
        rwLock.writeLock().lock();
        try {
            System.out.println("synchronizedMethod1 called");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("synchronizedMethod1 done");
        } finally {
            rwLock.writeLock().unlock();
        }
    }
    public void method1() {
        rwLock.readLock().lock();
        try {
            System.out.println("Method 1 called");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Method 1 done");
        } finally {
            rwLock.readLock().unlock();
        }
    }
}
于 2012-07-18T20:25:09.800 に答える