Inter Thread Communication-Java

时间:2015-11-15 01:29:26

标签: java multithreading

我是java线程的新手。我无法在以下代码中将锁定从主线程返回给线程。我得到了不受欢迎的输出,因为我无法解锁线程。我希望线程使用线程递增值(之后进入等待状态)并在打印值后,释放锁以打印下一个递增的值。

   class Foo implements Runnable 
    {
         public volatile int value=0,i=0;
        Thread t=new Thread();
       public void method(Thread t) 
        {
          this.t = t;
       }

         @Override
         public synchronized void run() 
         {

            while(i<3)
            {
            value++;//receive and process ACK
             i++;
            try
            {
           System.out.println("im thread here");
            wait();  
            System.out.println("passed wait");
            }
            catch(InterruptedException ex){
            }
            System.out.println("im notified");
             }//while 
             //}//sync
         }//run method

         public int getValue()
         {

             try
        {
          Thread.sleep(1000);
        }
         catch (Exception e) {
          System.out.println(e);
        } 
             return value;
         }
     }//class foo

     public class ThreadTest
    {
      public static int value1,times=0;
      public static void main(String[] args) 
      {
        Foo foo=new Foo();
        Thread t=new Thread(foo);
        foo.method(t);
        t.start();
        while(times<3)
        {   
             synchronized(t)
           {
           value1=foo.getValue();
           times++;
           System.out.println(value1);
           System.out.println(t.getState()); 
               try
            {
            t.notify();
             System.out.println("Notify is reached");
             }
            catch(IllegalMonitorStateException ex)
            {
            System.out.println("Thread is blocked");
            } 
        }//sync
        }//while
       }//main
    }//mclasss

2 个答案:

答案 0 :(得分:0)

目前还不清楚你真正想做什么,但是我们假设你想在后台运行一个线程,该线程只有在它的生成器(让主线程允许)允许的情况下才能运行。

JDK已经有了几个工具,不需要依赖低级wait()和notify {,All}()方法。

这种原语的一个例子是CountDownLatch。它是一个一次性使用的实体,允许您在任何线程countDown()触发之前指定给定线程集应该.await()的时间。

结合早在Java 1.5中出现的多线程处理类,这意味着您可以执行以下操作:

// Implementation of a Runnable waiting for the counter to trigger
public final class MyWaitingClass
    implements Runnable
{
    private final CountDownLatch latch;

    public MyWaitingClass(final CountDownLatch latch)
    {
        this.latch = latch;
    }

    @Override
    public void run()
    {
        try {
            latch.await();
            // do whatever is necessary
        } catch (InterruptedException e) {
            // Argh; interrupted before the latch was released
            Thread.currentThread().interrupt();
        }
    }
}

// In the main class:
final ExecutorService executor = Executors.newSingleThreadPool();
final CountDownLatch latch = new CountDownLatch(1); 
final Runnable runnable = new MyWaitingClass(latch);
executor.submit(runnable);
// do whatever is needed; then:
latch.countDown();

答案 1 :(得分:0)

你正试图这样做吗?如果你真的必须使用wait / notify&amp;想要使用Runnable。

我添加了一个等待块,否则主线程可能会在后台线程增加值之前完成。

class Foo implements Runnable {
    public volatile int value = 0, i = 0;
    private Thread backgroundThread;

    public void setThread(Thread thread) {
        this.backgroundThread = thread;
    }

    @Override
    public void run() {
        synchronized (backgroundThread) {
            while (i < 2) {
                value++;
                i++;
                backgroundThread.notify();
                try {
                    System.out.println("background thread wait start");
                    backgroundThread.wait();
                    System.out.println("background thread notified");
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }

    public int getValue() {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }
}

public class ThreadTest {
    public static int value1, times = 0;

    public static void main(String[] args) {
        Foo foo = new Foo();
        final Thread thread = new Thread(foo);
        foo.setThread(thread);
        thread.start();

        while (times < 3) {
            synchronized (thread) {
                value1 = foo.getValue();
                times++;
                System.out.println(value1);
                System.out.println(thread.getState());
                thread.notify();
                try {
                    thread.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

或者你可以扩展线程:

class BackgroundThread extends Thread {
    public volatile int value = 0, i = 0;

    @Override
    public synchronized void run() {
        while (i < 2) {
            value++;
            i++;
            notify();
            try {
                System.out.println("background thread wait start");
                wait();
                System.out.println("background thread notified");
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    public int getValue() {
        try {
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }
}

public class ThreadTest {
    public static int value1, times = 0;

    public static void main(String[] args) {
        BackgroundThread backgroundThread = new BackgroundThread();
        backgroundThread.start();

        while (times < 3) {
            synchronized (backgroundThread) {
                value1 = backgroundThread.getValue();
                times++;
                System.out.println(value1);
                System.out.println(backgroundThread.getState());
                backgroundThread.notify();
                try {
                    backgroundThread.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}