• Java中的线程间通信


    什么是轮询,它有什么问题?

    反复测试条件直到其变为真的过程称为轮询。

    轮询通常是借助循环来实现的,以检查特定条件是否为真。如果为真,则将采取某些措施。这浪费了许多CPU周期,并使实现效率低下。
    例如,在一个经典的排队问题中,一个线程正在产生数据而另一个线程正在消耗数据。

    Java多线程如何解决这个问题?
    为了避免轮询,Java使用三种方法,即wait(),notify()和notifyAll()。
    所有这些方法最终都属于对象类,因此所有类都具有它们。它们只能在同步块中使用。

    • wait()-它告诉调用线程放弃锁定并进入睡眠状态,直到其他线程进入同一监视器并调用notify()为止。
    • notify()-唤醒一个在同一对象上调用wait()的单个线程。应该注意的是,调用notify()实际上并没有放弃对资源的锁定
    • notifyAll()-唤醒同一对象上所有调用wait()的线程。

    一个简单的Java程序来演示这三种方法

    // Java program to demonstrate inter-thread communication 
    // (wait(), join() and notify()) in Java 
    import java.util.Scanner; 
    public class threadexample 
    { 
        public static void main(String[] args) 
                               throws InterruptedException 
        { 
            final PC pc = new PC(); 
      
            // Create a thread object that calls pc.produce() 
            Thread t1 = new Thread(new Runnable() 
            { 
                @Override
                public void run() 
                { 
                    try
                    { 
                        pc.produce(); 
                    } 
                    catch(InterruptedException e) 
                    { 
                        e.printStackTrace(); 
                    } 
                } 
            }); 
      
            // Create another thread object that calls 
            // pc.consume() 
            Thread t2 = new Thread(new Runnable() 
            { 
                @Override
                public void run() 
                { 
                    try
                    { 
                        pc.consume(); 
                    } 
                    catch(InterruptedException e) 
                    { 
                        e.printStackTrace(); 
                    } 
                } 
            }); 
      
            // Start both threads 
            t1.start(); 
            t2.start(); 
      
            // t1 finishes before t2 
            t1.join(); 
            t2.join(); 
        } 
      
        // PC (Produce Consumer) class with produce() and 
        // consume() methods. 
        public static class PC 
        { 
            // Prints a string and waits for consume() 
            public void produce()throws InterruptedException 
            { 
                // synchronized block ensures only one thread 
                // running at a time. 
                synchronized(this) 
                { 
                    System.out.println("producer thread running"); 
      
                    // releases the lock on shared resource 
                    wait(); 
      
                    // and waits till some other method invokes notify(). 
                    System.out.println("Resumed"); 
                } 
            } 
      
            // Sleeps for some time and waits for a key press. After key 
            // is pressed, it notifies produce(). 
            public void consume()throws InterruptedException 
            { 
                // this makes the produce thread to run first. 
                Thread.sleep(1000); 
                Scanner s = new Scanner(System.in); 
      
                // synchronized block ensures only one thread 
                // running at a time. 
                synchronized(this) 
                { 
                    System.out.println("Waiting for return key."); 
                    s.nextLine(); 
                    System.out.println("Return key pressed"); 
      
                    // notifies the produce thread that it 
                    // can wake up. 
                    notify(); 
      
                    // Sleep 
                    Thread.sleep(2000); 
                } 
            } 
        } 
    } 

    输出:

    producer thread running
    Waiting for return key.
    Return key pressed
    Resumed

    如果您仍然对为什么我们在消耗线程中使用了通知感到困惑,请尝试将其删除并再次运行您的程序。正如您现在必须已经注意到的那样,该程序永远不会终止。
    这样做的原因很简单-当您在生产线程上调用wait时,它继续等待并且从未终止。由于程序一直运行到其所有线程终止,因此它将一直运行。
    解决这个问题还有第二种方法。您可以使用wait()的第二种变体。

    void wait(long timeout) 

    这将使调用线程仅在指定的时间内休眠。

  • 相关阅读:
    OS + Linux + zipTool / tar / tar.gz / zst
    project scm
    product wiki confluence
    script ActionScript / ColdFusion
    链表例题
    链表原理
    链表例题
    链表原理
    链表原理
    链表原理
  • 原文地址:https://www.cnblogs.com/crelle/p/13887533.html
Copyright © 2020-2023  润新知