在多线程编程中,线程间的通信是保证程序正确性和效率的关键。以下介绍四种常见的线程间通信技巧,帮助你在编程中实现高效协作。
1. 等待/通知机制(Wait/Notify)
等待/通知机制是Java等语言中常用的一种线程间通信方式。通过Object.wait()和Object.notify()方法,可以使一个线程在某个对象上等待,直到另一个线程调用该对象的notify()或notifyAll()方法唤醒它。
示例代码:
public class WaitNotifyExample {
public static void main(String[] args) {
Object lock = new Object();
Thread producer = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("生产者生产产品...");
lock.notify();
}
}
});
Thread consumer = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费者消费产品...");
}
}
});
producer.start();
consumer.start();
}
}
2. 信号量(Semaphore)
信号量是Java并发编程中的一个重要工具,可以控制多个线程对共享资源的访问权限。通过Semaphore类,可以创建一个具有特定数量的许可的信号量,线程在访问共享资源之前必须先获取许可。
示例代码:
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(1);
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("线程1获取信号量");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("线程2获取信号量");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
});
thread1.start();
thread2.start();
}
}
3. 管道(Pipe)
管道是Java并发编程中的一种线程间通信方式,它允许一个线程向管道中写入数据,另一个线程从管道中读取数据。通过Pipe.Sink和Pipe.Source接口,可以轻松实现线程间的数据传输。
示例代码:
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PipeExample {
public static void main(String[] args) throws Exception {
PipedInputStream pipedInputStream = new PipedInputStream();
PipedOutputStream pipedOutputStream = new PipedOutputStream(pipedInputStream);
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(() -> {
try {
Thread.sleep(1000);
pipedOutputStream.write("Hello World!".getBytes());
pipedOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
});
executorService.submit(() -> {
try {
System.out.println(new String(pipedInputStream.readAllBytes()));
} catch (Exception e) {
e.printStackTrace();
}
});
executorService.shutdown();
}
}
4. 共享内存(Shared Memory)
共享内存是一种允许多个线程直接访问同一块内存空间的通信方式。在Java中,可以通过java.nio包中的MappedByteBuffer实现共享内存。
示例代码:
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
public class SharedMemoryExample {
public static void main(String[] args) throws Exception {
Path path = Paths.get("shared-memory");
FileChannel fileChannel = FileChannel.open(path, java.nio.file.StandardOpenOption.CREATE, java.nio.file.StandardOpenOption.READ, java.nio.file.StandardOpenOption.WRITE);
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
new Thread(() -> {
try {
buffer.put("Hello World!".getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
Thread.sleep(1000);
System.out.println(new String(buffer.array()));
} catch (Exception e) {
e.printStackTrace();
}
}).start();
fileChannel.close();
}
}
以上四种线程间通信技巧各有特点,适用于不同的场景。掌握这些技巧,有助于你在多线程编程中实现高效协作。
