Java的阻塞方法
Java中的阻塞方法是阻塞线程直到其操作完成的特定方法集。因此,他们将不得不阻塞当前线程,直到满足完成任务的条件为止。因为,本质上,这些方法是阻塞的,所谓的阻塞方法。例如,InputStream read()方法会阻塞,直到所有 InputStream 数据都被完全读取。以下是一些最常见的Java阻塞方法:
- InvokeAndWait():等待Event Dispatcher线程执行代码。
- InputStream.read():它阻塞直到输入数据可用、抛出异常或检测到流结束。
- ServerSocket.accept():侦听入站Java套接字连接并阻塞,直到建立连接。
- 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