2つのスレッドと2つのメソッドを持つ1つのオブジェクトがあるとします。 スレッド1はmethod1を使用します。 スレッド1で使用されているmethod1はまだを実行していますが、スレッド2ではmethod2を使用できますか?異なるスレッドが同じオブジェクトの異なる独立したメソッドに同時にアクセスできますか?
このすべては、オブジェクトがマルチスレッド化を念頭に置いて作成されたものではないことを前提としています(同期化も似ていなくても)、メソッドは同じ変数にアクセスしません。
このコードは、それが可能であることを示唆している:here
から
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class multithreadaccess {
/**
* @param args
* the command line arguments
*/
public static void main(String[] args) throws IOException {
TestClass tc = new TestClass();
// invokes not sync method
FirstThreadRunnable ftr = new FirstThreadRunnable(tc);
Thread t1 = new Thread(ftr);
// invokes the sync method
SecondThreadRunnable str = new SecondThreadRunnable(tc);
Thread t2 = new Thread(str);
t1.start();
t2.start();
System.in.read();
}
public static class TestClass {
private int callCount = 0;
public void secondmethod() {
System.out.println("second method activated! Call number:" + " [" + callCount++ + "] from thread: "
+ Thread.currentThread().getId());
}
public void firstmethod() throws InterruptedException {
// Test with the sleep
System.out.println("starting first slow method from thread: " + Thread.currentThread().getId());
Thread.sleep(1000); // hold the monitor for 5sec
System.out.println("stopping first slow method! Call number:" + " [" + callCount++ + "] from thread: "
+ Thread.currentThread().getId());
// Test with spinning
/*
* System.out.println("MAKE IT SPIN! from thread: " +
* Thread.currentThread().getId()); boolean spin = true;
* while(spin){
*
* } System.out.println("IT STOPPED SPINNING! from thread: " +
* Thread.currentThread().getId()); }
*/
}
}
// invokes the not sync method
public static class FirstThreadRunnable implements Runnable {
TestClass tester = null;
public FirstThreadRunnable(TestClass tester) {
this.tester = tester;
}
@Override
public void run() {
try {
tester.firstmethod();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// invokes the sync method
public static class SecondThreadRunnable implements Runnable {
TestClass tester = null;
public SecondThreadRunnable(TestClass tester) {
this.tester = tester;
}
@Override
public void run() {
tester.secondmethod();
}
}
}
変更されたコードでも、私はこれが可能であるかを理解していません。私はいつもオブジェクトが線形コードだと考えていました。しかし、これは、linearはメソッド内のコードだけであることを示唆しています(変数が複数のメソッドで使用されていない限り)。
実際に共有変数があり、これが競合状態を引き起こす可能性がありますが、これはコードが(callCountの状況を除いて)最初のメソッドを呼び出し、2番目のメソッドを開始して終了し、最初のメソッドを終了します。私はいつも何らかの自動ブロック(同じオブジェクトから別のメソッドが実行されている間はあるメソッドへのアクセスがない)があると思っていましたが、何もありませんでしたか?任意のスレッドが任意のオブジェクトの任意のメソッドをいつでも実行できることを意味しますか? – harbun
@harbunいいえいいえあなたが書いたように「自動ブロック」はありません。これは正確に 'AtomicInteger'のようなクラスが存在する理由です。 – Will
通常、ロックや' synchronized'キーワードで実装される「自動ブロック」は、これらの操作が高価でプログラムが遅くなるため、デフォルトではありません。 – Will