`
Cb123456
  • 浏览: 66011 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

线程同步

    博客分类:
  • java
阅读更多

线程同步:

 一、线程同步:

  线程的同步,就是要保证线程在执行某个计算时,需要保证相关的数据在这个计算过程中只能被一个线程访问,即保证访问数据的原子性---就像一个坐位,只能同时被一个人(线程)所使用。

 

 二、举例,以在银行取钱为例子:

   1.创建账户:

 

package 线程同步;
/**
 * 银行账户对象
 * @author Administrator
 *
 */
public class Account {

	private int total=0;
	//构造有指定金额的银行账户
	public Account(int save){
		this.total = save;
	}
	
	public String toString(){
		
		return "账户余额:"+total;
	}
	
	//取钱的
	private void disSave(int count){
		try{
			Thread.sleep(1000);
		}catch(Exception ed){
				
		}
		
		total=total-count;
		
	}
	
	//从账户上提取现金的调用方法
	public   int getCash(int count){
		//金额不足
		if (total<count) {
			return -1;
		}
		
		//从账户上减去提取金额
		disSave(count);
		
		return count;
		
	}
	
}

 

 

  2.取钱线程:

package 线程同步;

public class GetCashThread extends Thread {

	private  Account ac;//操作账户
	private  String flag;//取钱方式
	private  int disCount;//取现金额
	
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		//super.run();
		//在这里取钱
		
		//synchronized (ac) {
			
			int cash=ac.getCash(disCount);
			System.out.println(flag+"取了:"+cash);
		//}
		
	}




	public GetCashThread(Account ac,String flag,int disCount){
		
		this.ac = ac;
		this.flag = flag;
		this.disCount = disCount;
		
	}
	
}

  

 

   3.Main类:

package 线程同步;

public class DriverBank {

	public static void main(String[] args) {
		//创建一个账号:
		Account ac = new Account(5000);
		
		//从ATM取
		GetCashThread atmGet = new GetCashThread(ac, "ATM取款", 2500);
		
		//从柜台取
		GetCashThread counterGet = new GetCashThread(ac, "从柜台取款", 2600);
		
		//启动取款线程
		atmGet.start();
		counterGet.start();
		
		//主线程暂停,等到前面两个取款线程完成,打印出账户余额
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(ac);
		
	}
}

  

 三、运行结果:

   
 

     账户共有5000,可是分别取到2500,2600,余额是-100,这就是线程不同步,所造成的结果.ATM的线程取钱时,柜台取钱进入取钱,此时的ATM的线程还未结算完,导致账户上还是5000,

 

 四、处理

  解决原理:避免多个线程同时操作某一个对象的数据,就要让多线程操作对象的数据时候有一个先后顺序,一个操作完成另一个线程在操作的。

 

    解决1---使用synchronized关键字

  这个关键字可以放在一个方法前,表示这个方法同时只能被一个线程访问,或通过锁定某个对象放在代码块前,表示其限定的代码块只能同时被一个线程防问。

 代码改善:

		synchronized (ac) {
			int cash=ac.getCash(disCount);
			System.out.println(flag+"取了:"+cash);
		}
		

 运行结果:

 
 
 

 解决2--使用java.util.concurrent

 这个包中有许多对并发编程有良好支持的类,其中新增了一个java.util.concurrent.locks.Lock接口,这是一个对象的接口,它的多个实现的子类可用来支持线程同步时灵活的锁机制

 代码改善:

package 线程同步;
import java.util.concurrent.locks.*;
import java.util.concurrent.locks.ReentrantLock;

public class GetCashThread extends Thread {

	private  Account ac;//操作账户
	private  String flag;//取钱方式
	private  int disCount;//取现金额
	
	//定义一个同步锁
	private static Lock myLock = new ReentrantLock();
	
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		//super.run();
		//在这里取钱
		
			
		try{
			myLock.lock();// 仅有一个线程可同时执行此段代码
			int cash=ac.getCash(disCount);
			System.out.println(flag+"取了:"+cash);
		}finally{
			myLock.unlock();
		}
			

	}




	public GetCashThread(Account ac,String flag,int disCount){
		
		this.ac = ac;
		this.flag = flag;
		this.disCount = disCount;
		
	}
	
}

 运行结果:

 
 
 

五、总结.

  避免多线程同时操作某一对象的数据,要给线程加上执行顺序.

 

  • 大小: 5.5 KB
  • 大小: 4.3 KB
  • 大小: 6.4 KB
1
0
分享到:
评论

相关推荐

    vc++中的线程锁(线程锁保持线程同步)

    在VC++编程环境中,线程同步是一个至关重要的概念,特别是在多线程程序设计中,以确保并发执行的线程能够安全地访问共享资源,避免数据竞争和其他潜在的问题。本篇文章将详细探讨线程锁在VC++中的应用,以及如何通过...

    C#线程同步的几种方法

    标题与描述概述的知识点主要集中在C#中的线程同步技术,包括`volatile`关键字、`lock`关键字以及`System.Threading.Interlocked`类的使用。在深入探讨这些知识点之前,我们首先需要理解为什么线程同步在多线程环境中...

    线程同步的五种方法

    线程同步是多线程编程中的重要概念,用于协调多个并发执行的线程,确保它们在访问共享资源时不会产生竞态条件或数据不一致性。在Windows编程中,提供了多种线程同步机制,包括互斥量、临界区、原子操作、事件以及...

    操作系统线程同步实验报告

    操作系统线程同步是多线程编程中的核心概念,旨在确保并发执行的线程在访问共享资源时不会引发数据不一致性和竞态条件。本实验报告详细探讨了这一主题,通过一个简单的银行账户转账的示例来揭示临界区问题及其解决...

    线程同步的四种方式

    在多线程编程中,线程同步是一种控制多个线程并发执行时访问共享资源的方式,以避免数据不一致和死锁等问题。以下是对线程同步的四种主要方式的详细解释: 1. **事件(Event)** 事件是Windows API提供的一种线程...

    线程同步解决火车站售票问题

    在这个“线程同步解决火车站售票问题”的例子中,我们可以通过线程同步机制来实现售票的有序、无冲突的过程。 首先,我们需要理解问题的核心:10个售票处(线程)需要共享1000张票(资源),并且每卖出一张票,必须...

    操作系统实验多线程同步(含C++源代码)

    操作系统中的多线程同步是一个关键概念,特别是在并发编程中,它涉及到如何协调多个线程以避免数据不一致性和竞态条件。在这个实验中,我们关注的是C++编程语言中的实现,以及操作系统如何处理线程的优先级。 首先...

    简单实现多线程同步示例(模拟购票系统)

    本示例“简单实现多线程同步示例(模拟购票系统)”旨在通过一个具体的实例,帮助开发者理解如何在Java中创建并管理多线程以及如何实现线程同步,确保数据的一致性和正确性。 首先,我们要明确多线程的基本概念。在...

    VC++线程同步实例

    在编程领域,线程同步是多线程编程中的一个重要概念,它确保了多个线程在访问共享资源时的正确性和一致性。在这个“VC++线程同步实例”中,我们将探讨如何利用VC++(Visual C++)来实现线程间的同步,以避免数据竞争...

    操作系统线程同步算法

    操作系统中的线程同步是多线程编程中一个关键的概念,它确保了多个线程在访问共享资源时的正确性,防止数据竞争和其他并发问题。在Windows操作系统中,提供了多种线程同步机制,如临界区、事件、信号量以及互斥量等...

    Delphi多线程同步的例子

    本文将深入探讨Delphi中的多线程和线程同步,并以"SortThreads"和"delphi-thread-gui"这两个示例项目为例,讲解如何在实践中应用这些概念。 1. **多线程**:多线程允许应用程序同时执行多个独立的任务,提高程序的...

    多线程及线程同步

    然而,多线程环境下也带来了一些问题,尤其是资源竞争和数据一致性问题,这些问题需要通过线程同步机制来解决。本文将详细介绍如何通过临界区、互斥内核对象、事件内核对象和信号量内核对象来实现线程同步。 1. ...

    Java多线程同步.pdf

    "Java多线程同步.pdf" Java多线程同步是指在Java语言中,如何使用synchronized关键字和其他同步机制来确保多线程程序的正确执行。在Java语言中,synchronized关键字用于对方法或者代码块进行同步,但是仅仅使用...

    线程同步小例子

    在编程领域,线程同步是多线程编程中的一个核心概念,它涉及到如何有效地管理和协调多个并发执行的线程,确保它们能正确地共享资源,避免数据竞争和死锁等问题。这个“线程同步小例子”是基于孙鑫先生著作中的示例...

    操作系统实验 多线程同步与互斥 java编写 有界面

    操作系统实验是计算机科学教育中的重要组成部分,它帮助学生理解和掌握操作系统的基本原理,特别是多线程同步与互斥的概念。在Java编程环境下,这些概念可以通过实际的代码实现来深入理解。 多线程是现代操作系统中...

    多线程的批量线程同步解决方案

    "多线程的批量线程同步解决方案"这个标题暗示我们探讨的是如何在多线程环境下有效地管理和同步多个任务,确保数据一致性与程序正确性。下面将详细阐述相关知识点。 一、多线程基础 多线程是指在一个进程中同时执行...

    Jni多线程同步事例

    在本例“Jni多线程同步事例”中,我们将探讨如何在JNI层面上实现多线程同步,特别是在一个生产者-消费者模型的场景下。 生产者-消费者模型是一种经典的并发问题,它涉及到两个或多个线程之间的协作。在该模型中,...

    c#线程同步的典型例子

    C#线程同步是多线程编程中的一个重要概念,它涉及到如何控制多个线程对共享资源的访问,以避免数据不一致性和竞态条件。在C#中,线程同步通常用于确保在某一时刻只有一个线程可以访问特定的代码块或资源,从而保证...

Global site tag (gtag.js) - Google Analytics