卡塔尔世界杯_中国进过几次世界杯 - 210rc.com
首页世界杯波兰正文

【愚公系列】2023年10月 Java教学课程 072

2025-06-18 00:43:57

🚀一、线程通信🔎1.线程通信的概念和使用在Java中,线程间的通信是指多个线程之间协调工作以完成任务的过程。线程通信可以通过共享的数据结构来实现,也可以使用Java提供的一些机制(如wait、notify、notifyAll)来实现。

使用wait、notify、notifyAll机制实现线程的通信,需要满足以下条件:

必须在同步块中调用wait、notify、notifyAll方法。

必须拥有该对象的监视器(synchronized代码块)的锁。

该对象调用wait方法时,线程进入等待状态,直到被notify或notifyAll方法唤醒。

该对象调用notify方法时,会随机唤醒一个在等待的线程。

该对象调用notifyAll方法时,会唤醒所有在等待的线程。

下面是一个使用wait和notify机制实现线程通信的示例:

代码语言:javascript代码运行次数:0运行复制public class ThreadCommunication {

private static Object lock = new Object();

private static boolean flag = false;

public static void main(String[] args) {

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

synchronized (lock) {

while(!flag) {

try {

lock.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("Thread1 is running.");

}

}

});

Thread t2 = new Thread(new Runnable() {

@Override

public void run() {

synchronized (lock) {

flag = true;

lock.notify();

System.out.println("Thread2 is running.");

}

}

});

t1.start();

t2.start();

}

}在这个示例中,我们创建了两个线程t1和t2,并在t1中使用了wait方法,在t2中使用了notify方法。当t1线程启动后,进入同步块后发现flag为false,就调用了wait方法,线程进入等待状态。t2线程启动后,进入同步块后将flag设置为true,并调用notify方法,唤醒一个等待中的线程(即t1线程),t1线程被唤醒后输出"Thread1 is running."。

🔎2.线程通信常见形式Java中线程通信的常见形式有:

wait()和notify()方法:通过Object类提供的wait()和notify()方法实现线程之间的通信,wait()方法可以让当前线程等待,直到另一个线程调用notify()方法唤醒它。一般情况下,wait()和notify()方法需要与同步锁一起使用。

BlockingQueue:BlockingQueue是一个队列,它支持线程安全的插入和删除操作,可以用于实现线程间的通信。阻塞队列有put方法和take方法,当队列已满时,put方法会阻塞;当队列为空时,take方法会阻塞。

Semaphore:Semaphore是一种计数器,它可以限制同时访问某个资源的线程数量。通过Semaphore可以实现线程之间的通信和同步。

CountDownLatch:CountDownLatch是一种同步辅助工具,它可以让某个线程等待其他线程完成操作之后再执行。使用CountDownLatch可以实现线程间的协作和同步。

CyclicBarrier:CyclicBarrier是一种同步辅助工具,它可以让一组线程在达到某个屏障点之前互相等待。使用CyclicBarrier可以实现线程之间的协作和同步。

🔎3.应用场景在Java中,线程通信的应用场景主要有以下几种:

生产者消费者模型:在该模型中,有一个生产者线程用于生产数据,而有一个或多个消费者线程用于消费数据。生产者线程需要将生产的数据传递给消费者线程,因此需要通过线程通信来实现。

等待-通知机制:在该机制中,一个线程需要等待另一个线程执行完毕后再进行操作。例如,一个线程需要等待另一个线程将数据写入共享变量中后再进行读取。这时,可以使用等待-通知机制实现线程之间的协作。

线程间协作:在某些情况下,多个线程需要协作完成某项任务,例如多个线程协同处理一个大型数据集。此时,需要通过线程通信来实现数据的共享和协作。

GUI界面更新:在Java中,GUI界面是由一个主线程(称为事件调度线程)维护的。当GUI应用程序需要执行一些长时间的操作时,为避免阻塞主线程,可以将这些操作放到一个独立的线程中执行。然而,当这些操作完成后,需要将结果通知给主线程,让它更新GUI界面,此时就需要使用线程通信来实现。

多线程并发控制:在多线程并发控制中,需要对多个线程的执行顺序和时间进行控制,以保证程序的正确性和一致性。例如,在一个并发程序中,需要确保读写操作的顺序和时序正确,此时就需要使用线程通信来实现。

🔎4.案例以下是一个简单的Java线程通信案例,其中有两个线程,一个生产者和一个消费者。

生产者线程将数字1到10放入一个共享的缓冲区中,消费者线程从缓冲区中获取这些数字并打印它们。

在这个案例中,生产者和消费者之间通过 wait() 和 notify() 方法进行通信。

代码语言:javascript代码运行次数:0运行复制public class ThreadCommunication {

public static void main(String[] args) {

final Buffer buffer = new Buffer();

// 生产者线程

Thread producerThread = new Thread(() -> {

for (int i = 1; i <= 10; i++) {

buffer.put(i);

try {

Thread.sleep(1000); // 线程睡眠1秒

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

// 消费者线程

Thread consumerThread = new Thread(() -> {

for (int i = 1; i <= 10; i++) {

int value = buffer.get();

System.out.println("消费者获取的值为:" + value);

}

});

producerThread.start(); // 启动生产者线程

consumerThread.start(); // 启动消费者线程

}

}

/**

* 共享的缓冲区

*/

class Buffer {

private int value;

private boolean hasValue = false; // 缓冲区中是否有值

/**

* 生产者向缓冲区中放值

*/

public synchronized void put(int value) {

while (hasValue) { // 如果缓冲区中已有值,则等待

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("生产者放入的值为:" + value);

this.value = value;

hasValue = true;

notify(); // 唤醒等待的线程

}

/**

* 消费者从缓冲区中取值

*/

public synchronized int get() {

while (!hasValue) { // 如果缓冲区中没有值,则等待

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

int value = this.value;

hasValue = false;

notify(); // 唤醒等待的线程

return value;

}

}

瑞士糖价格 Win10提示“无法保存IP设置,请检查一个或多个设置并重试”怎么办?
相关内容