`

java concurrent (1) - 传统线程互斥和通信

阅读更多
线程互斥是一次只有一个线程执行某段代码,保证数据的一致性。线程通信是指通过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中实现线程间的同步与互斥。 生产者消费...

    Java 实例 - 查看线程优先级源代码+详细指导教程.zip

    `java.util.concurrent`包中的`BlockingQueue`、`Future`和`Callable`接口可以实现线程间的通信和结果获取。 通过解压并分析这个压缩包中的源代码和教程,你可以了解到如何在实际项目中应用线程优先级,并理解其...

    线程间资源互斥与通信(生产者消费者)

    在多线程编程中,线程间的资源互斥与通信是关键问题,这涉及到系统并发性能和程序的正确性。本实例将深入探讨"生产者消费者"模型,这是线程间通信的一个经典案例,用于展示如何高效地共享有限资源。 生产者消费者...

    第20章 Part3 多线程互斥与协作.pdf

    ### 第20章 Part3:多线程互斥与协作 #### 一、互斥(Mutual Exclusion) 互斥是指在线程编程中确保多个线程不会同时访问同一资源的技术。这种技术非常重要,因为如果不加以控制,多个线程对共享资源的并发访问...

    java10个线程按照顺序打印1-100

    1. **synchronized**:在Java中,`synchronized`关键字用于提供互斥访问,确保同一时间只有一个线程可以访问特定的代码块。例如,可以创建一个公共的方法或同步块,所有线程都会在进入这个区域前等待其他线程完成。...

    Java 线程通信示例 源代码

    线程通信主要涉及两个核心概念:同步和互斥。 1. **线程同步**:线程同步是为了防止多个线程同时访问共享资源,从而可能导致数据不一致或错误。Java提供了多种同步机制,如`synchronized`关键字、`wait()`, `notify...

    java经典多线程面试题

    - 使用Condition接口提供的await()、signal()和signalAll()方法在java.util.concurrent.locks包中的实现类也可以实现线程间的通信。 10. Java中的并发集合类有哪些? - java.util.concurrent包中提供了一些线程...

    线程互斥和同步代码样本滴水三期信号量布置的作业

    线程互斥和同步是多线程编程中的关键概念,它们确保了在并发环境中资源的安全访问和程序的正确执行。在计算机系统中,一个进程可能包含多个线程,这些线程共享同一内存空间,因此必须有机制来防止线程间的冲突。 ...

    java实现多线程间的通信

    Java 实现多线程间的通信在软件开发中至关重要,特别是在Android和Java应用开发中。本文将探讨线程间通信的概念,分析基于Java的多线程程序的关键技术,并指出设计多线程程序时需要充分理解线程同步机制以及操作系统...

    java多线程

    由于提供的文件内容大部分与Java多线程编程核心技术并无直接关联,而是关于电子书资源的联系方式和说明,因此不能直接从这部分内容中生成关于Java多线程的知识点。但考虑到描述中提到了电子书的标题以及它涉及的主题...

    java多线程实现生产者和消费者

    `synchronized`用于互斥访问,`wait()`, `notify()`和`notifyAll()`用于线程间的通信。`BlockingQueue`接口提供了线程安全的队列,自动处理了等待和唤醒操作,是实现生产者-消费者模型的一种高效方式。 4. **条件...

    concurrent-patterns-best-practices-synchronization

    - **生产者消费者模式**:该模式通过一个缓冲区来协调生产者线程和消费者线程之间的数据交换,有效避免了直接通信带来的复杂性。 - **读写分离模式**:通过将读操作与写操作分开处理,可以显著减少并发冲突,提高...

    JAVA线程学习(源代码)

    另外,`java.util.concurrent`包中的BlockingQueue是一个高效的线程间通信工具,它提供了插入和移除元素的阻塞操作,常用于生产者-消费者模式。 异常处理在多线程编程中也至关重要。如果一个线程在运行过程中抛出未...

    JAVA多线程通信学习_服务器多线程通信_

    在Java编程中,多线程通信是构建高效并发应用程序的关键技术。服务器多线程通信尤其重要,因为它允许服务器同时处理多个客户端请求,提高系统资源利用率并优化响应时间。本篇文章将深入探讨Java中的多线程通信,以及...

    深入理解JAVA多线程之线程间的通信方式

    在Java多线程编程中,线程间的通信是至关重要的,因为它确保了多个并发执行的任务能够协调工作,避免数据不一致性和死锁等问题。本文将深入探讨两种主要的线程间通信方式:同步机制和基于轮询的方式。 1. 同步机制...

    java线程安全-往盘子里放鸡蛋和向盘子里取鸡蛋

    在Java中,我们可以使用`synchronized`关键字来确保线程安全,它提供了互斥访问,使得在任意时刻只有一个线程能够执行特定的代码块。为了实现"放鸡蛋"和"取鸡蛋"的操作,我们可以定义两个方法:`putEgg()`和`takeEgg...

    创建线程式-多线程学习

    1. **Java**: Java 提供了 `Thread` 类和 `Runnable` 接口来创建线程,还有 `ExecutorService` 和 `ThreadPoolExecutor` 来管理线程池。`synchronized` 关键字和 `java.util.concurrent` 包提供了丰富的同步工具。 ...

    java源码总结-Java-Concurrent-Programming:java并发编程学习总结源码部分

    源码中可能包括了如何创建自定义线程、控制线程的启动、暂停、恢复和终止,以及线程间通信的方法如`join()`和`interrupt()`。 同步机制是保证多线程安全的关键,Java提供了多种方式实现线程同步,如`synchronized`...

Global site tag (gtag.js) - Google Analytics