线程互斥是一次只有一个线程执行某段代码,保证数据的一致性。线程通信是指通过notify或notifyAll来唤醒在wait某个对象锁的线程。实现方式是通过synchronized关键字声明。
1. 如果同步代码块在对象方法中,可以实例化一个Object来作为lock的对象,或者用this关键字表示lock这个对象:
synchronized(obj) {
// code block
}
synchronized(this) {
// code block
}
2. 如果同步代码块在静态方法中,使用一个静态对象,如当前class的字节码来作为lock的对象:
synchronized(CurrentClass.class) {
// code block
}
3. synchronized修饰整个方法,这时锁的对象就是当前实例化的对象,保证一次只有一个线程执行这个方法:
public synchronized void warranty() {
// code segment
}
public synchronized void merchantability() {
// code segment
}
如果对象的两个或两个以上方法都加了synchronized修饰符,则一次只能由一个线程执行其中的某一个方法。
我们可以把需要互斥执行的代码分别放到这些方法里实现互斥,然后辅以wait和notify实现通信,看下面的例子:
主线程执行100次A代码后,由辅线程执行10次B代码,然后再由主线程执行100次A代码,辅线程10次B代码,如此循环40次。
public class TraditionalConcurrentCommunication {
public static void main(String[] args) {
// Ensure to operate the same object
final Cooperation cooperation = new Cooperation();
// Main thread
new Thread(new Runnable() {
@Override
public void run() {
for (int t = 1; t <= 40; t++) {
try {
cooperation.first(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
// Sub thread
new Thread(new Runnable() {
@Override
public void run() {
for (int t = 1; t <= 40; t++) {
try {
cooperation.second(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
static class Cooperation {
private boolean bFirst = true;
public synchronized void first(int times) throws InterruptedException {
while (!bFirst) { // 使用状态标志防止伪唤醒
wait(); // 在当前对象上等待被唤醒
}
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " is executing first() in loop of " + i
+ " of the " + times + " times");
}
bFirst = false;
notify(); // 通知在当前对象上等待的线程,即Sub thread
}
public void second(int times) throws InterruptedException {
while (bFirst) {
wait();
}
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + " is executing second() in loop of " + i
+ " of the " + times + " times");
}
bFirst = true;
notify(); // 通知在当前对象上等待的线程,即Main thread
}
}
}
这里把业务逻辑放到一个类的两个方法中,体现了面向对象的编程思想。
分享到:
相关推荐
在Java编程中,线程同步和互斥是多线程编程中的重要概念,它们用于解决多个线程同时访问共享资源时可能出现的问题。本项目通过一个生产者消费者问题的实例,展示了如何在Java中实现线程间的同步与互斥。 生产者消费...
`java.util.concurrent`包中的`BlockingQueue`、`Future`和`Callable`接口可以实现线程间的通信和结果获取。 通过解压并分析这个压缩包中的源代码和教程,你可以了解到如何在实际项目中应用线程优先级,并理解其...
在多线程编程中,线程间的资源互斥与通信是关键问题,这涉及到系统并发性能和程序的正确性。本实例将深入探讨"生产者消费者"模型,这是线程间通信的一个经典案例,用于展示如何高效地共享有限资源。 生产者消费者...
### 第20章 Part3:多线程互斥与协作 #### 一、互斥(Mutual Exclusion) 互斥是指在线程编程中确保多个线程不会同时访问同一资源的技术。这种技术非常重要,因为如果不加以控制,多个线程对共享资源的并发访问...
1. **synchronized**:在Java中,`synchronized`关键字用于提供互斥访问,确保同一时间只有一个线程可以访问特定的代码块。例如,可以创建一个公共的方法或同步块,所有线程都会在进入这个区域前等待其他线程完成。...
线程通信主要涉及两个核心概念:同步和互斥。 1. **线程同步**:线程同步是为了防止多个线程同时访问共享资源,从而可能导致数据不一致或错误。Java提供了多种同步机制,如`synchronized`关键字、`wait()`, `notify...
- 使用Condition接口提供的await()、signal()和signalAll()方法在java.util.concurrent.locks包中的实现类也可以实现线程间的通信。 10. Java中的并发集合类有哪些? - java.util.concurrent包中提供了一些线程...
线程互斥和同步是多线程编程中的关键概念,它们确保了在并发环境中资源的安全访问和程序的正确执行。在计算机系统中,一个进程可能包含多个线程,这些线程共享同一内存空间,因此必须有机制来防止线程间的冲突。 ...
Java 实现多线程间的通信在软件开发中至关重要,特别是在Android和Java应用开发中。本文将探讨线程间通信的概念,分析基于Java的多线程程序的关键技术,并指出设计多线程程序时需要充分理解线程同步机制以及操作系统...
由于提供的文件内容大部分与Java多线程编程核心技术并无直接关联,而是关于电子书资源的联系方式和说明,因此不能直接从这部分内容中生成关于Java多线程的知识点。但考虑到描述中提到了电子书的标题以及它涉及的主题...
`synchronized`用于互斥访问,`wait()`, `notify()`和`notifyAll()`用于线程间的通信。`BlockingQueue`接口提供了线程安全的队列,自动处理了等待和唤醒操作,是实现生产者-消费者模型的一种高效方式。 4. **条件...
- **生产者消费者模式**:该模式通过一个缓冲区来协调生产者线程和消费者线程之间的数据交换,有效避免了直接通信带来的复杂性。 - **读写分离模式**:通过将读操作与写操作分开处理,可以显著减少并发冲突,提高...
另外,`java.util.concurrent`包中的BlockingQueue是一个高效的线程间通信工具,它提供了插入和移除元素的阻塞操作,常用于生产者-消费者模式。 异常处理在多线程编程中也至关重要。如果一个线程在运行过程中抛出未...
在Java编程中,多线程通信是构建高效并发应用程序的关键技术。服务器多线程通信尤其重要,因为它允许服务器同时处理多个客户端请求,提高系统资源利用率并优化响应时间。本篇文章将深入探讨Java中的多线程通信,以及...
这种特性使得线程间的通信更为高效,但也需要特别注意同步和互斥问题,以免出现数据不一致或死锁等问题。 - **Java线程的重要性**:Java线程对于提高程序性能至关重要,尤其是在处理用户界面(UI)响应性和利用多...
在Java多线程编程中,线程间的通信是至关重要的,因为它确保了多个并发执行的任务能够协调工作,避免数据不一致性和死锁等问题。本文将深入探讨两种主要的线程间通信方式:同步机制和基于轮询的方式。 1. 同步机制...
1. java.util.concurrent包下的工具类,如CountDownLatch、CyclicBarrier、Semaphore等,用于协调多个线程之间的操作。 以上内容只是《Java多线程编程核心技术》教程中的一部分核心知识点,实际学习中还需要结合...
在Java中,我们可以使用`synchronized`关键字来确保线程安全,它提供了互斥访问,使得在任意时刻只有一个线程能够执行特定的代码块。为了实现"放鸡蛋"和"取鸡蛋"的操作,我们可以定义两个方法:`putEgg()`和`takeEgg...
1. **Java**: Java 提供了 `Thread` 类和 `Runnable` 接口来创建线程,还有 `ExecutorService` 和 `ThreadPoolExecutor` 来管理线程池。`synchronized` 关键字和 `java.util.concurrent` 包提供了丰富的同步工具。 ...