Java使线程阻塞
在Java中,线程是一种轻量级的执行单元,可以同时运行多个线程来完成任务。线程的阻塞是指线程在某些条件下暂停执行,直到满足特定条件后再继续执行。线程阻塞可以通过多种方式实现,包括睡眠、等待、锁和IO操作等。本文将介绍Java中不同的线程阻塞方法,并提供相应的代码示例。
1. 线程睡眠
在线程需要暂停一段时间后再继续执行时,可以使用线程睡眠方法Thread.sleep()
。该方法使当前线程暂停执行指定的时间,单位为毫秒。
下面是一个使用线程睡眠的示例代码:
public class SleepExample {
public static void main(String[] args) {
System.out.println("开始执行");
try {
Thread.sleep(2000); // 线程睡眠2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("继续执行");
}
}
在上述代码中,主线程调用Thread.sleep(2000)
使线程睡眠2秒,然后继续执行。
2. 线程等待
线程等待是指线程在某个条件满足之前一直等待,直到条件满足后再继续执行。Java中,可以使用Object
的wait()
和notify()
方法实现线程等待和唤醒。
下面是一个使用线程等待和唤醒的示例代码:
public class WaitNotifyExample {
public static void main(String[] args) {
final Object lock = new Object();
Thread thread1 = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("线程1开始等待");
lock.wait(); // 线程1等待
System.out.println("线程1被唤醒");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock) {
System.out.println("线程2唤醒线程1");
lock.notify(); // 唤醒线程1
}
});
thread1.start();
thread2.start();
}
}
在上述代码中,线程1通过synchronized
关键字获取对象锁,并调用wait()
方法等待。线程2获取同一个对象锁,并调用notify()
方法唤醒线程1。
3. 线程锁
线程锁是一种常用的线程阻塞方法,用于控制多个线程对共享资源的访问。Java中,可以使用synchronized
关键字实现线程锁。
下面是一个使用线程锁的示例代码:
public class LockExample {
private static int count = 0;
public static void main(String[] args) {
final Object lock = new Object();
Thread thread1 = new Thread(() -> {
synchronized (lock) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
});
Thread thread2 = new Thread(() -> {
synchronized (lock) {
for (int i = 0; i < 10000; i++) {
count--;
}
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("count = " + count);
}
}
在上述代码中,两个线程同时对变量count
进行加减操作,为了保证线程安全,通过synchronized
关键字对共享资源进行锁定。
4. 线程IO阻塞
在Java中,线程可能因为IO操作而阻塞,例如文件读写和网络通信等。当线程执行IO操作时,如果数据未准备好或无法立即发送,线程会被阻塞,直到IO操作完成。
下面是一个使用线程IO阻塞的示例代码:
public class IOBlockingExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
FileInputStream fis = new FileInputStream("input.txt");