这些Java线程是否处于解除锁定状态?

这些Java线程是否处于解除锁定状态?,java,multithreading,Java,Multithreading,我已经编写了一个示例程序来说明如何使用pipeis线程。我已经创建了2个线程 Thread1正在发送“Hi this is Thread1”,并调用wait()等待线程2完成 Thread2正在打印thread1发送的消息,并且还将附加到字符串缓冲区中,然后一旦接收到整个消息,Thread2将打印字符串缓冲区的内容并调用notify。现在,在调用wait()和notify之后,两个线程都处于死锁状态 奇怪的是,thread2打印消息one,但不打印字符串缓冲区的内容 package com.tu

我已经编写了一个示例程序来说明如何使用pipeis线程。我已经创建了2个线程

  • Thread1正在发送“Hi this is Thread1”,并调用wait()等待线程2完成

  • Thread2正在打印thread1发送的消息,并且还将附加到字符串缓冲区中,然后一旦接收到整个消息,Thread2将打印字符串缓冲区的内容并调用notify。现在,在调用wait()和notify之后,两个线程都处于死锁状态

  • 奇怪的是,thread2打印消息one,但不打印字符串缓冲区的内容

    package com.tuto.MultiThreading;
    
    import java.io.IOException;
    import java.io.PipedInputStream;
    import java.io.PipedOutputStream;
    
    public class PipeExample {
    
        public static void main(String[] args) throws IOException, InterruptedException {
            final Object obj=new Object();
            final PipedOutputStream pipeoutstream=new PipedOutputStream ();
            final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
    
            Thread thread1= new Thread(new Runnable()
            {
    
                public void run() {
                    try {
                        pipeoutstream.write("Hello I am thread1".getBytes());
                        synchronized (obj) 
                        {
    
                            obj.wait(); 
                        }
    
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    finally
                    {
                        try {
                            pipeoutstream.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }   
                    }
    
                }
    
            });
    
    
              Thread thread2 = new Thread(new Runnable() {
                    public void run() {
                        try {
    
                            int data = pipeinputstream.read();
                            StringBuffer sb=new StringBuffer();
                            while(data != -1){
                                System.out.print((char) data);
                                sb.append((char)data);
                                data = pipeinputstream.read();
                            }
                            System.out.println();
                            System.out.println(sb.toString());
                            synchronized (obj) {
    
                                obj.notify();
                            }
    
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        finally
                        {
                            try {
                                pipeinputstream.close();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }   
                        }
                    }
                });
    
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.exit(1);
        }
    }
    
    输出:: 你好,我是thread1

    更新决议:

    package com.tuto.MultiThreading;
    
    import java.io.IOException;
    import java.io.PipedInputStream;
    import java.io.PipedOutputStream;
    
    public class PipeExample {
    
        public static void main(String[] args) throws IOException, InterruptedException {
            final Object obj=new Object();
            final PipedOutputStream pipeoutstream=new PipedOutputStream ();
            final PipedInputStream pipeinputstream=new PipedInputStream(pipeoutstream);
    
            Thread thread1= new Thread(new Runnable()
            {
    
                public void run() {
                    try {
                        pipeoutstream.write("Hello I am thread1".getBytes());
    
    
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    finally
                    {
                        try {
                            pipeoutstream.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }   
                        synchronized (obj) 
                        {
    
                            try {
                                obj.wait();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }   
                        }
                    }
    
                }
    
            });
    
    
              Thread thread2 = new Thread(new Runnable() {
                    public void run() {
                        try {
    
                            int data = pipeinputstream.read();
                            StringBuffer sb=new StringBuffer();
                            while(data != -1){
                                System.out.print((char) data);
                                sb.append((char)data);
                                data = pipeinputstream.read();
                            }
                            System.out.println();
                            System.out.println(sb.toString());
                            synchronized (obj) {
    
                                obj.notify();
                            }
    
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        finally
                        {
                            try {
                                pipeinputstream.close();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }   
                        }
                    }
                });
    
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.exit(1);
        }
    }
    
    现在我有点困惑了。我刚把wait()从try catch移到finally。它是如何影响管道流阻塞的?

    问题在于

    data = pipeinputstream.read();
    
    线程2中有一个阻塞调用。来自

    此方法将一直阻止,直到输入数据可用为止,即 检测到流,或引发异常

    线程2一直在等待,直到其中一个事件发生。由于它们都不会发生,线程将无法通知另一个线程

    这不是僵局


    请注意,即使该调用未被阻止并返回-1,线程2仍然可以在线程1调用
    wait
    之前执行其
    notify
    。在这种情况下,线程1将是一个处于持续等待状态的线程,并且您的程序将不会终止。

    其中是否有问题?或者你只是在做一个状态报告?嗨,我把等待从“尝试”改为“最终”,结果成功了。那么为什么等待会影响pipestream呢?如果该调用未被阻止并返回-1,线程2仍然可以在线程1调用wait之前执行其notify。在这种情况下,线程1将是一个处于持续等待状态的线程,并且您的程序不会终止。这是错误的,因为它来自while和print字符串缓冲区contents@MacleanPinto
    wait
    阻止线程1关闭流并取消阻止线程2对
    read
    @MacleanPinto的调用。您无法控制线程调度程序。让我们看看你的新解决方案。如果线程调用
    close
    ,并且有一个上下文切换,那么线程2现在就可以执行了。假设它执行所有操作,包括
    notify
    调用,在出现另一个上下文切换之前,线程2将通过调用
    wait
    继续。这样就没有什么东西可以通知它了。