`
lcy0202
  • 浏览: 178238 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

线程同步(二)—synchronized

 
阅读更多


当多线程共享一个数据时候,就会容易因为编程不对而导致出现错误。比如,两个线程对一个数据进行修改,由于线程调度的不确定性,导致出现错误。所以,java引进了synchronized进行对共享数据的保护,确保在一个线程在对数据进行修改处理的时候,其他线程不能对该数据进行修改访问。

   实例:模拟 银行取钱

1.实体类对象:Account.java

 

       package thread.account;

public class Account
{
	private String accountNo;
	private double balance;
public Account(){}

	public Account(String accountNo , double balance)
	{
		this.accountNo = accountNo;
		this.balance = balance;
	}

	public void setAccountNo(String accountNo)
	{
		this.accountNo = accountNo;
	}
	public String getAccountNo()
	{
		 return this.accountNo;
	}

	public double getBalance()
	{
		 return this.balance;
	}
//同步方法,使方法线程方法安全,不被多个线程同时访问修改
	public synchronized void draw(double drawAmount)
	{
		//账户余额大于取钱数目
		if (balance >= drawAmount)
		{
			//吐出钞票
			System.out.println(Thread.currentThread().getName() + 
				"取钱成功!吐出钞票:" + drawAmount);
			try
			{
				Thread.sleep(1);			
			}
			catch (InterruptedException ex)
			{
				ex.printStackTrace();
			}
			//修改余额
			balance -= drawAmount;
			System.out.println("\t余额为: " + balance);
		}
		else
		{
			System.out.println(Thread.currentThread().getName() +
				"取钱失败!余额不足!");
		}
	}

	public int hashCode()
	{
		return accountNo.hashCode();
	}
	public boolean equals(Object obj)
	{
		if (obj != null && obj.getClass() == Account.class)
		{
			Account target = (Account)obj;
			return target.getAccountNo().equals(accountNo);
		}
		return false;
	}
}
 

 

 2.  线程对象 DrawThread.java


 package thread.account;

public class DrawThread extends Thread
{
	//模拟用户账户
	private Account account;
	//当前取钱线程所希望取的钱数
	private double drawAmount;

	public DrawThread(String name , Account account , 
		double drawAmount)
	{
		super(name);
		this.account = account;
		this.drawAmount = drawAmount;
	}

	//当多条线程修改同一个共享数据时,将涉及到数据安全问题。
	public void run()
	{
		account.draw(drawAmount);
	}
}

 3.  测试 TestDraw.java


 package thread.account;
public class TestDraw
{
    public static void main(String[] args) 
    {
		//创建一个账户
		Account acct = new Account("1234567" , 1000);
		//模拟两个线程对同一个账户取钱
		new DrawThread("甲" , acct , 800).start();
		new DrawThread("乙" , acct , 800).start();
    }
}

那么synchronized是如何释放资源的呢?答:所有对象都自动含有单一的锁,JVM负责跟踪对象被加锁的次数。如果一个对象被解锁,其计数变为0。在任务(线程)第一次给对象加锁的时候,计数变为1。每当这个相同的任务(线程)在此对象上获得锁时,计数会递增。每当任务离开一个synchronized方法,计数递减,当计数为0的时候,锁被完全释放,此时别的任务就可以使用此资源。


注:在jdk1.5之后,java提供了Lock进行同步处理,Lock能实现synchronized的所有功能,而且性能比synchronized高,我接下来继续讲Lock 



 

分享到:
评论

相关推荐

    java的线程同步机制synchronized关键字的理解_.docx

    Java 线程同步机制中 synchronized 关键字的理解 Java 的线程同步机制是为了解决多个线程共享同一片存储空间所带来的访问冲突问题。其中,synchronized 关键字是 Java 语言中解决这种冲突的重要机制。 ...

    线程同步(synchronized)1---马克-to-win java视频 java视频

    线程同步(synchronized)1---马克-to-win java视频 java视频

    线程同步(synchronized)2---马克-to-win java视频

    线程同步(synchronized)2---马克-to-win java视频的介绍

    Java线程及同步(synchronized)样例代码

    `synchronized`是Java中用于实现线程同步的重要关键字之一。它可以修饰方法或代码块,保证同一时刻只有一个线程能够访问被修饰的部分,从而实现对共享资源的保护。当一个对象的实例方法或静态方法被`synchronized`...

    Java多线程同步.pdf

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

    正确使用多线程同步锁@synchronized()1

    总结起来,`@synchronized`是一种便捷的多线程同步手段,通过递归互斥锁实现代码的原子性。在使用时应注意以下几点: 1. `@synchronized`是基于对象的,传入的对象不能为`nil`,否则无效。 2. 由于使用了递归锁,它...

    java 线程同步 信号量控制同步

    关于线程同步,需要牢牢记住的第二点是 “共享”这两个字。只有共享资源的读写访问才需要同步。如果不是共享资源,那么就根本没有同步的必要。 关于线程同步,需要牢牢记住的第三点是,只有“变量”才需要同步访问...

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

    二、线程同步 线程同步是多线程编程中的重要概念,用于控制不同线程间的执行顺序和访问共享资源的方式,防止竞态条件和死锁的发生。常见的线程同步机制包括: 1. **互斥量(Mutex)**:一种简单的同步机制,一次只有...

    线程同步面试题深入解析

    在Java中,线程同步主要通过`synchronized`关键字来实现,防止多个线程同时访问临界区,以避免出现不可预期的结果。 1. **synchronized修饰同步方法** 使用`synchronized`关键字修饰的方法称为同步方法。同步方法...

    Java、Android多线程、线程安全、线程同步

    NoHttp核心架构之多线程通信、线程安全、线程同步;synchronized锁,Lock锁;具体讲解请移步博客:http://blog.csdn.net/yanzhenjie1003/article/details/50992468

    线程同步Synchronized,监视器monitor和锁lock的关系2---马克-to-win java视频

    线程同步Synchronized,监视器monitor和锁lock的关系2---马克-to-win java视频

    NET多线程同步方法详解

    .NET中的多线程同步是确保在并发环境下多个线程安全访问共享资源的关键技术。本文将深入探讨.NET框架中实现线程同步的多种方法。 首先,我们来看自由锁(InterLocked)。自由锁主要通过Interlocked类提供的静态方法来...

    多线程同步和通讯完整示例

    synchronized关键字提供了基本的线程同步,而wait-notify机制和Lock接口则提供了更高级的线程通讯和控制手段。在实际开发中,根据具体需求选择合适的同步策略,可以提高程序的效率和正确性。通过学习和实践...

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

    为了实现线程同步,Java提供了多种机制,如synchronized关键字、wait()、notify()和notifyAll()方法,以及Lock接口(如ReentrantLock)等。在这个示例中,我们可能会用到synchronized关键字来修饰购票的方法,这样...

    售票窗口模拟线程同步

    在Java中,线程同步可以通过多种方式实现,其中最常见的就是`synchronized`关键字和显式锁(如`ReentrantLock`)。在本案例中,使用的是`synchronized`关键字。 1. **synchronized关键字**:当`synchronized`用于...

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

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

    java 多线程同步方法的实例

    Java提供了多种机制来实现线程同步,主要包括synchronized关键字、wait()、notify()和notifyAll()方法以及ReentrantLock等。 1. **synchronized关键字**:这是Java中最基本的线程同步方式。它可以用于修饰方法或...

    iOS线程同步方案

    然而,多线程同时也带来了线程安全的问题,这就需要我们掌握线程同步方案来确保数据的一致性和完整性。本文将深入探讨iOS中的线程同步策略,包括互斥锁、自旋锁和递归锁。 1. **互斥锁(Mutex)**: 互斥锁是一种...

Global site tag (gtag.js) - Google Analytics