- 共享变量:可以通过在两个线程中定义一个共享变量,然后使用 synchronized(volatile
) 关键字确保线程安全,实现数据的读取和修改。
public class 共享变量01 {
private int value;
public synchronized int getValue() {
return value;
}
public synchronized void setValue(int value) {
this.value = value;
}
public static void main(String[] args) {
共享变量01 data = new 共享变量01();
Thread thread1 = new Thread(() -> {
data.setValue(10);
});
Thread thread2 = new Thread(() -> {
data.setValue(20);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
int value = data.getValue();
System.out.println(value);
});
thread2.start();
thread1.start();
}
}
public class 共享变量02 {
static volatile boolean notice = false;
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Thread threadA = new Thread(() ->{
for (int i = 1; i <= 10; i++){
list.add("nga");
System.out.println("线程A向列表中添加一个元素, 此时list中元素个数为: " + list.size());
try {
Thread.sleep(500);
} catch (InterruptedException e){
e.printStackTrace();
}
if (list.size() == 5)
notice = true;
}
});
Thread threadB = new Thread(() -> {
while (true){
if (notice){
System.out.println("线程B收到通知, 开始执行自己的业务: ");
break;
}
}
});
threadB.start();
threadA.start();
}
}
2、使用Object类的wait()和notify() 方法
public static void main(String[] args) {
// 定义一个锁对象
Object lock = new Object();
ArrayList<String> list = new ArrayList<>();
// 实现线程A
Thread threadA = new Thread(() -> {
synchronized (lock){
for (int i = 1; i <= 10; i++){
list.add("A"+i);
System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (list.size() == 5){
// 唤醒 B线程
System.out.println("线程A,lock.notify()...");
lock.notify();
}
}
}
});
// 实现线程B
Thread threadB = new Thread(() -> {
synchronized (lock){
if(list.size() != 5){
try {
System.out.println("线程B,lock.wait()...");
lock.wait();
System.out.println("线程B,lock.wait()结束...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程B收到通知,开始执行自己的业务...");
}
});
threadB.start();
threadA.start();
}
3、使用CountDownLatch方法
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(1);
ArrayList<String> list = new ArrayList<>();
Thread threadA = new Thread(() -> {
for (int i = 0; i <= 10; i++){
list.add("pcr");
System.out.println("线程A向list中添加一个元素,此时list中的元素个数为:" + list.size());
if (list.size() == 5){
System.out.println("线程A,countDownLatch.countDown()...");
countDownLatch.countDown();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread threadB = new Thread(() -> {
if (list.size() != 5){
try {
System.out.println("线程B,countDownLatch.wait()...");
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程B收到通知,开始执行自己的业务...");
});
threadB.start();
threadA.start();
}
- 管道:使用 PipedOutputStream 和 PipedInputStream 可以实现线程间的管道通信。
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class Main {
public static void main(String[] args) throws IOException {
PipedOutputStream outputStream = new PipedOutputStream();
PipedInputStream inputStream = new PipedInputStream();
outputStream.connect(inputStream);
Thread thread1 = new Thread(() -> {
try {
outputStream.write(10);
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
});
Thread thread2 = new Thread(() -> {
try {
int value = inputStream.read();
inputStream.close();
System.out.println(value);
} catch (IOException e) {
e.printStackTrace();
}
});
thread1.start();
thread2.start();
}
}