0

2つのクラスがあります。クラスの一方のメソッドはもう一方のクラスのメソッドを呼び出しますが、メソッドが終了するまで待機して、残りのコードの実行に進む必要があります。

これは私が作ろうとしているものの大まかなコードです。そして、私はこれが機能しないことを知っています。

public class Example 
{
    Thread thread;

    public Example(Thread thread)
    {
        this.thread = thread;
    }

    public void doSomethingElse()
    {
        System.out.println("Do something else");
        thread.notify();
    }
}

public class Example2 
{
    Thread thread;
    Example example;

    public Example2()
    {
        example = new Example(thread);
        thread = new Thread()
        {
            public void run()
            {
                example.doSomethingElse();
                try {
                    this.wait();
                } catch (InterruptedException ex) {                    
                }
                System.out.println("Do something");
            }
        };
    }

    public void doSomething()
    {
        thread.run();
    }
}

今、あなたはこれを正しくする方法を知っていますか?

4

3 に答える 3

0

ポイントのカップル:

  • waitまたはnotifyメソッドを呼び出す前にロックを取得する必要があります。ロックは同じオブジェクト上にある必要があります。コードでは、example2オブジェクトでwaitを呼び出していますが、別のオブジェクトでnotifyを呼び出しています。
  • thread.run()は、スレッドオブジェクトのrunメソッドを呼び出すことを意味し、example.doSomething()と同じように新しいスレッドを作成しません。スレッドを作成するときは、startメソッドを呼び出してそのスレッドを開始します。

これが私の実装です

    class Example implements Runnable 
    {
        public void run()
        {
            doSomething();
        }
        public void doSomething(){
            synchronized(this){
                System.out.println("Do something else");
                try{
                   Thread.sleep(1000); 
                   this.notify();    
                }catch (InterruptedException ignore) {}            
            }    
        }
    }

    class Example2 implements Runnable 
    {
        Thread thread;
        Example example;

        public Example2(Example example){
            this.example = example;
        }


        public void run(){
            doSomething();    
        }

        public void doSomething(){
            synchronized(example){
                System.out.println("waiting for example 1 to complete");
                try{
                    example.wait();    
                }catch (InterruptedException ignore) {}

            }
            System.out.println("Do something");
        }
    }

    public class Entry{
        public static void main(String[] args){

            Example example = new Example();

            Example2 obj = new Example2(example);
            Thread t = new Thread(obj);
            t.start();

            Thread t2 = new Thread(example);
            t2.start();
        }
    }

コードThread.sleep(1000); ステートメントは必要ありません。

于 2012-12-14T06:33:54.397 に答える
0

これがjoinメソッドを使用したもう1つの実装です

    class Example implements Runnable 
    {
        public void run()
        {
            doSomething();
        }
        public void doSomething(){
            System.out.println("Do something else");

            try{
                Thread.sleep(1000);    
            }catch (InterruptedException ignore) {}                
        }
    }

    class Example2 implements Runnable 
    {
        Thread thread;
        Example example;

        public Example2(Example example){
            this.example = example;
        }


        public void run(){
            System.out.println("waiting for example 1 to complete");
            Thread t = new Thread(example);
            try{
                t.start();
                t.join();
            }catch(InterruptedException ie){

            }

            doSomething();    
        }

        public void doSomething(){
            System.out.println("Do something");
        }
    }

    public class Entry{
        public static void main(String[] args){

            Example example = new Example();

            Example2 obj = new Example2(example);
            Thread t = new Thread(obj);
            t.start();
        }
    }
于 2012-12-14T06:45:51.253 に答える
0

この特定のアプローチ(待機/通知)の使用に制約があるかどうかはわかりませんが、より良いアプローチはJavaConcurrencyAPIを利用しています。

public class ExampleCountDownLatch
{
    public void doSomething () throws InterruptedException
    {
        final CountDownLatch latch = new CountDownLatch(1);

        Thread thread = new Thread()
        {
            public void run ()
            {
                System.out.println("do something");
                latch.countDown();
            }
        };

        System.out.println("waiting for execution of method in your example class");
        thread.start();
        // wait for reasonable time otherwise kill off the process cause it took
        // too long.
        latch.await(3000, TimeUnit.MILLISECONDS);

        // now I can do something from your example 2
        System.out.println("now i can execute from example 2 do something else");
    }
}

とにかく、オプションがあれば、別のアプローチです。

アップデート:

これはまさにこのトピックに関するブログです。

于 2012-12-14T06:52:40.900 に答える