Java线程互斥和同步一直是一个较难理解透彻的东西,要弄清楚其本真,还是要先从概念入手:
1、线程之间通过对资源的竞争,包括共享的数据和硬件资源,所产生的相互制约关系,这类线程间的主要问题是互斥和死锁问题,这类关系被称为互斥关系。
2、线程之间的相互协同合作,彼此之间直接知道对方的存在,并了解对方的名字,这类进程常常需要通过“进程间通信”方法来协同工作,这类关系被称为同步关系。
概念读几遍,至少能把互斥和同步分清楚,然后我们来详细看看互斥,以及java线程间怎么来实现互斥。
举个银行取钱的例子:一个用户有2000块钱,同时有两个人在操作这个账户进行取钱,一次取100块,分别取四次。
package bank_test; public class UserGetMoney implements Runnable { // 模拟用户取款的线程类 private static int sum = 2000; public void take(int k) { int temp = sum; temp -= k; try { Thread.sleep((int) (100 * Math.random())); } catch (InterruptedException e) { } sum = temp; System.out.println(Thread.currentThread() + "sum = " + sum); } int money = 0; public UserGetMoney(int money) { // TODO Auto-generated constructor stub this.money = money; } public void run() { for (int i = 1; i <= 4; i++) { take(money); } } }
以上是ATM机取钱的主类
package bank_test; public class BankAdvance { // 调用线程的主类 public static void main(String[] args) { UserGetMoney u1 = new UserGetMoney(100); new Thread(u1).start(); new Thread(u1).start(); } }
运行结果:
Thread[Thread-1,5,main]sum = 1900 Thread[Thread-0,5,main]sum = 1900 Thread[Thread-1,5,main]sum = 1800 Thread[Thread-0,5,main]sum = 1800 Thread[Thread-0,5,main]sum = 1700 Thread[Thread-1,5,main]sum = 1700 Thread[Thread-1,5,main]sum = 1600 Thread[Thread-0,5,main]sum = 1600
看到,结果两个人取了八次,账户只少了400块,明显是没有互斥,所以导致银行亏了1倍的钱。要解决这个问题,就要用到关键字synchronized了,它用于实现语句的同步操作,即给共享资源加互斥锁。
锁定一个对象和一段代码
声明格式为:
synchronized(<对象名 >){
<语句组>
}
锁定一个方法
声明格式为:
synchronized<方法声明 >{
<方法体>
}
线程间的互斥
无论是对方法加互斥锁,还是对对象加互斥锁,其实质都是实现对共享资源的互斥访问
互斥操作是以降低应用程序的并发程度为代价的
因此,在编写多线程程序中,对synchronized的使用就遵循以下两个原则:
-不需要再多个线程中使用共享资源时,那么就没有必要使用该关键字;
-如果某个方法只是返回对象的值,而不去修改对象的值时,那么也就没有必要使用该关键字。
我们来改造下以上的代码:
package bank_test; public class UserGetMoney implements Runnable { // 模拟用户取款的线程类 private static int sum = 2000; public synchronized void take(int k) { // 限定take为同步方法 int temp = sum; temp -= k; try { Thread.sleep((int) (100 * Math.random())); } catch (InterruptedException e) { } sum = temp; System.out.println(Thread.currentThread() + "sum = " + sum); } int money = 0; public UserGetMoney(int money) { // TODO Auto-generated constructor stub this.money = money; } public void run() { for (int i = 1; i <= 4; i++) { take(money); } } }
再来看看结果:
相关推荐
本项目通过一个生产者消费者问题的实例,展示了如何在Java中实现线程间的同步与互斥。 生产者消费者问题是经典的并发问题之一,它涉及到两个类型的线程:生产者和消费者。生产者负责生成数据(产品),而消费者则...
摘要:Java源码,系统相关,线程同步,线程互斥 Java线程间同步互斥,在实际的编程中,经常要处理线程间的同步互斥问题。Java 语言内在强大的多线程支持使得处理这类问题变得相对来说比较简单。本例将模仿经典的线程...
在“操作系统实验 多线程同步与互斥 java编写 有界面”的实验中,可能需要设计一个图形用户界面(GUI),通过按钮或事件触发线程的创建和同步操作,直观地展示线程间的交互和同步效果。例如,可以模拟银行账户转账,...
下面是一个简单的Java PV操作示例,模拟了两个线程对一个共享资源(如打印机)的互斥访问: ```java import java.util.concurrent.Semaphore; public class PrintService { private Semaphore printerSemaphore =...
总的来说,掌握线程互斥和同步是成为一名优秀软件开发者不可或缺的技能,通过实践和理论的结合,你可以在解决复杂并发问题时游刃有余。在滴水三期的作业中,你应该有机会深入理解和应用这些概念,通过编写实际代码...
**线程互斥** 是线程同步的一种特殊形式,确保同一时间只有一个线程能够访问特定的资源。互斥锁是实现线程互斥的常用工具。当一个线程获取了互斥锁后,其他试图获取该锁的线程会被阻塞,直到持有锁的线程释放它。在...
标题中的"java 多线程synchronized互斥锁demo"指的是一个示例,展示了如何在多线程环境下使用`synchronized`关键字创建互斥锁,确保同一时间只有一个线程可以访问特定的代码块或方法。 描述中的"一个多线程访问的同...
线程互斥是指当多个线程访问同一临界资源时,同一时刻只允许一个线程进行操作,以防止数据竞争和不一致的状态。线程同步则是协调多个线程执行的顺序和条件,避免出现有害的并发行为,如死锁和饥饿。 在实现线程互斥...
在Windows等操作系统下,使用的VC、VB、java或C等编程语言,采用进程(线程)同步和互斥的技术编写程序实现生产者-消费者问题或哲学家进餐问题或读者-写者问题或自己设计一个简单进程(线程)同步和互斥的实际问题。
线程互斥的基本思想是,当一个线程正在访问共享资源时,其他试图访问该资源的线程会被阻塞,直到第一个线程完成其操作并释放资源。这通常通过使用锁(lock)来实现。在Java中,我们可以使用`synchronized`关键字或...
Java多线程同步是编程中一个非常重要的概念,特别是在并发编程和高并发系统设计中起到关键作用。在Java中,为了保证线程安全,避免数据竞争和不一致的状态,我们通常会使用同步机制来控制对共享资源的访问。本文将...
java多线程同步互斥访问实例,对于初学者或是温故而知新的同道中人都是一个很好的学习资料
Java语言中的线程同步互斥研究 1. 引言 在现代计算机系统中,程序的执行都需要占用处理器,因此处理器管理一直是操作系统的核心组成部分。为了合理利用资源,有效调度任务执行,现代操作系统采用并发的方式,调度...
在这个“多线程编程和操作系统线程同步互斥演示”中,作者可能创建了一个或多个人工场景,展示了如何在VC++环境中使用多线程,并且演示了线程同步和互斥的实践应用。这可能涉及到以下几个方面: 1. **线程创建**:...
在Java编程领域,ATM(Automated Teller Machine,自动取款机)模拟是一个常见的多线程问题,用于展示线程同步和互斥的概念。在这个场景中,ATM被设计成一个可以执行存款和取款操作的系统,而这些操作需要确保在并发...
在Java中,synchronized关键字是实现线程同步的关键,它提供了互斥访问,保证在任何时刻只有一个线程能够访问共享资源。 1. **synchronized关键字的使用** - **synchronized方法**:当一个方法被声明为...
线程互斥是一种同步机制,它的目标是限制同一时间只有一个线程能够访问特定的代码段或数据结构,这通常被称为临界区。当一个线程进入临界区时,其他试图访问该区域的线程会被阻塞,直到持有资源的线程完成其操作并...
学习Java线程,理解其创建、状态转换、调度和控制,以及如何处理线程间的互斥和同步,对于开发高效、稳定的并发程序至关重要。通过深入研究这些概念,开发者能够编写出更符合现代计算需求的高质量软件。
本文将深入探讨Java多线程中的关键知识点,包括创建线程、主线程、线程优先级、线程组、线程同步以及线程间的通信。 1. **创建线程** 在Java中,可以通过两种方式创建线程:继承`Thread`类或实现`Runnable`接口。...
### 第20章 Part3:多线程互斥与协作 #### 一、互斥(Mutual Exclusion) 互斥是指在线程编程中确保多个线程不会同时访问同一资源的技术。这种技术非常重要,因为如果不加以控制,多个线程对共享资源的并发访问...