java multi threading..thread相互通信

时间:2016-06-14 15:47:21

标签: java multithreading

我的问题与一次两个线程的工作有关,假设一个线程写一个文件并将资源释放到另一个线程以读取同一个文件,反之亦然。但是通信没有正确进行。这是代码片段

主题1

        public void run() {
            for(int i=1;i<10;i++) {
                System.out.println(i+"i");
                System.out.println("writing the  file");
                try {
                    synchronized (new A()) {
                        wait();
                    }

                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }

主题2

        public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
            for(int j=1;j<10;j++) {
                System.out.println(j+"j");
                System.out.println("reading the file");
                synchronized (new B()) {
                    notifyAll();    
                }
            }

2 个答案:

答案 0 :(得分:0)

同步发生在特定的监视器对象上。

在您的代码中,您可以使用new运算符为每个同步块创建新的监视器。

因此,您永远不会锁定对此代码片段的访问权限,因为其他线程无法使用其他监视器。

答案 1 :(得分:0)

这是经典的“生产者消费者/读者作家”并发问题。有几种方法可以解决这个问题 - 有些方法稍微过时,但对于像你这样的初学者来说更容易理解。

为了使2个或更多个线程相互依赖开始或结束,必须有一个共享对象或变量的概念,可以由每个线程更改,以通知其他线程当前线程完成。重要的是,任何时候只有一个线程正在更改共享对象(也称为临界区)。在这种情况下,您可以使用一些Java 8并发功能来同步这两个线程。下面是一个使用Java 8 Concurrency语法的简单示例,即ReadWriteLock,它是专门为此用例创建的。

public class ReaderWriterProblem {

   private ReentrantReadWriteLock theLock = new ReentrantReadWriteLock(true);

   public static void main(String[] args) {
      ReaderWriterProblem rwProblem = new ReaderWriterProblem();
      Reader reader1 = new Reader(theLock);
      Writer writer1 = new Writer(theLock);

      new Thread(reader1).start();
      new Thread(writer1).start();
   }

   private class Reader implements Runnable {
    private ReentrantReadWriteLock theLock;

    public Reader(ReentrantReadWriteLock theLock) {
         this.theLock = theLock;
      }

      public void run() {

         try {
            theLock.readLock().lock();
            System.out.println("Currently Reading!");
            try {
               Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
         } finally {
            theLock.readLock().unlock();
         }
      }
   }

   private class Writer implements Runnable {

    private ReentrantReadWriteLock theLock;

    public Writer(ReentrantReadWriteLock theLock) {
         this.theLock = theLock
      }

      public void run() {
         try {
            theLock.writeLock().lock();
            System.out.println("Currently Writing!");
            try {
               Thread.sleep(4000);
            } catch (InterruptedException e) {
            }
         } finally {
            theLock.writeLock().unlock();
         }

      }
   }
}

这是一个非常基本的例子,但ReadWriteLock实际上随时都支持一位作家和许多读者。因此,当一个线程持有写锁定时,没有其他线程可以同时写入,但是多个线程可以一次保持读锁定。

此问题的其他潜在解决方案包括信号量和忙碌等待,值得一看在线。

回答为什么你的问题是错误的 - 你需要同步共享对象和变量,而不是执行并发语句的类的实例。希望这有助于您了解更多。注意如何在读写器之间共享锁。