📜  Java的阻塞方法

📅  最后修改于: 2022-05-13 01:54:48.490000             🧑  作者: Mango

Java的阻塞方法

Java中的阻塞方法是阻塞线程直到其操作完成的特定方法集。因此,他们将不得不阻塞当前线程,直到满足完成任务的条件为止。因为,本质上,这些方法是阻塞的,所谓的阻塞方法。例如,InputStream read()方法会阻塞,直到所有 InputStream 数据都被完全读取。以下是一些最常见的Java阻塞方法:

  1. InvokeAndWait():等待Event Dispatcher线程执行代码。
  2. InputStream.read():它阻塞直到输入数据可用、抛出异常或检测到流结束。
  3. ServerSocket.accept():侦听入站Java套接字连接并阻塞,直到建立连接。
  4. CountDownLatch.await():使当前线程等待直到闩锁计数为零,除非线程被中断。

阻塞方法有几个缺点:

  • 阻塞技术对系统可扩展性构成重大威胁。经典的阻塞解决方案包括缓解阻塞的方法,使用多个线程为多个客户提供服务。
  • 设计是最重要的一个方面,因为即使多线程系统无法达到某个点,但由于JVM线程数量有限,设计不佳的系统也只能支持数百或数千个线程。

执行:

在下面的示例中,在执行第一个打印语句之后,程序将被第二个打印语句阻塞,直到在控制台中输入一些字符。然后点击回车,因为 read() 会阻塞该方法,直到某些输入可读为止。

示例 1:



Java
// Java Program to illsutare Blocking methods
 
// Importing all input output classes
import java.io.*;
 
// Class
class GFG {
 
   // main driver method
   public static void main(String args[]) throws FileNotFoundException, IOException 
 
   {
     // Print statement
     System.out.println("GFG");
 
     int result;
     result = System.in.read();
      
     // Print statement
     System.out.println("Geeks for Geeks");
 
   } 
 
}


Java
// Java Program to illsutare Blocking methods
 
// Importing all input output classes
import java.io.*;
// Importing concurrent CountDownLatch class
// from java.util package
import java.util.concurrent.CountDownLatch;
 
// Class
class GFG {
 
    // Main driver method
    public static void main(String args[])
        throws InterruptedException
    {
        // Let us create task that is going to wait
        // for five threads before it starts
        CountDownLatch latch = new CountDownLatch(4);
 
        // Creating threads of Person type
        // Custom parameter inputs
        Person p1 = new Person(1500, latch, "PERSON-1");
        Person p2 = new Person(2500, latch, "PERSON-2");
        Person p3 = new Person(3500, latch, "PERSON-3");
        Person p4 = new Person(4500, latch, "PERSON-4");
        Person p5 = new Person(5500, latch, "PERSON-5");
 
        // Starting the thread
        // using the start() method
        p1.start();
        p2.start();
        p3.start();
        p4.start();
        p5.start();
 
        // Waiting for the four threads
        // using the latch.await() method
        latch.await();
 
        // Main thread has started
        System.out.println(Thread.currentThread().getName()
                           + " has finished his work");
    }
}
 
// Class 2
// Helper class extending Thread class
// To represent threads for which the main thread waits
class Person extends Thread {
    // Member variables of this class
    private int delay;
    private CountDownLatch latch;
 
    // Method of this class
    public Person(int delay, CountDownLatch latch,
                  String name)
    {
        // super refers to parent class
        super(name);
 
        // This keyword refers to current object itself
        this.delay = delay;
        this.latch = latch;
    }
 
    @Override public void run()
    {
        // Try block to check for exceptions
        try {
            Thread.sleep(delay);
            latch.countDown();
 
            // Print the current thread by getting its name
            // using the getName() method
            // of whose work is completed
            System.out.println(
                Thread.currentThread().getName()
                + " has finished his work");
        }
 
        // Catch block to handle the exception
        catch (InterruptedException e) {
            // Print the line number where exception occured
            // using the printStackTrace() method
            e.printStackTrace();
        }
    }
}


输出
GFG
Geeks for Geeks

示例 2:

在这个例子中,当一个线程在开始工作之前需要等待其他线程时使用 CountDownLatch.await()。 CountDown() 方法减少 count 并且 wait() 方法阻塞直到 count == 0。

Java

// Java Program to illsutare Blocking methods
 
// Importing all input output classes
import java.io.*;
// Importing concurrent CountDownLatch class
// from java.util package
import java.util.concurrent.CountDownLatch;
 
// Class
class GFG {
 
    // Main driver method
    public static void main(String args[])
        throws InterruptedException
    {
        // Let us create task that is going to wait
        // for five threads before it starts
        CountDownLatch latch = new CountDownLatch(4);
 
        // Creating threads of Person type
        // Custom parameter inputs
        Person p1 = new Person(1500, latch, "PERSON-1");
        Person p2 = new Person(2500, latch, "PERSON-2");
        Person p3 = new Person(3500, latch, "PERSON-3");
        Person p4 = new Person(4500, latch, "PERSON-4");
        Person p5 = new Person(5500, latch, "PERSON-5");
 
        // Starting the thread
        // using the start() method
        p1.start();
        p2.start();
        p3.start();
        p4.start();
        p5.start();
 
        // Waiting for the four threads
        // using the latch.await() method
        latch.await();
 
        // Main thread has started
        System.out.println(Thread.currentThread().getName()
                           + " has finished his work");
    }
}
 
// Class 2
// Helper class extending Thread class
// To represent threads for which the main thread waits
class Person extends Thread {
    // Member variables of this class
    private int delay;
    private CountDownLatch latch;
 
    // Method of this class
    public Person(int delay, CountDownLatch latch,
                  String name)
    {
        // super refers to parent class
        super(name);
 
        // This keyword refers to current object itself
        this.delay = delay;
        this.latch = latch;
    }
 
    @Override public void run()
    {
        // Try block to check for exceptions
        try {
            Thread.sleep(delay);
            latch.countDown();
 
            // Print the current thread by getting its name
            // using the getName() method
            // of whose work is completed
            System.out.println(
                Thread.currentThread().getName()
                + " has finished his work");
        }
 
        // Catch block to handle the exception
        catch (InterruptedException e) {
            // Print the line number where exception occured
            // using the printStackTrace() method
            e.printStackTrace();
        }
    }
}
输出
PERSON-1 has finished his work
PERSON-2 has finished his work
PERSON-3 has finished his work
PERSON-4 has finished his work
main has finished his work
PERSON-5 has finished his work