Java多线程-线程的同步(同步方法)

转载 2013年12月02日 13:57:40
线程的同步是保证多线程安全访问竞争资源的一种手段。
线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源、什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些原则问题需要考虑,是否有竞争资源被同时改动的问题?

在本文之前,请参阅《Java多线程-线程的同步与锁》,本文是在此基础上所写的。

对于同步,在具体的Java代码中需要完成一下两个操作:
把竞争访问的资源标识为private;
同步哪些修改变量的代码,使用synchronized关键字同步方法或代码。
当然这不是唯一控制并发安全的途径。

synchronized关键字使用说明
synchronized只能标记非抽象的方法,不能标识成员变量。

为了演示同步方法的使用,构建了一个信用卡账户,起初信用额为100w,然后模拟透支、存款等多个操作。显然银行账户User对象是个竞争资源,而多个并发操作的是账户方法oper(int x),当然应该在此方法上加上同步,并将账户的余额设为私有变量,禁止直接访问。


package thread;

public class ThreadSynchronizedMethod {
	public static void main(String[] args) {
		ThreadSynchronizedMethod t = new ThreadSynchronizedMethod();
		User u = t.new User("张三", 100);
		MyThread t1 = t.new MyThread("线程A", u, 20);
		MyThread t2 = t.new MyThread("线程B", u, -60);
		MyThread t3 = t.new MyThread("线程C", u, -80);
		MyThread t4 = t.new MyThread("线程D", u, -30);
		MyThread t5 = t.new MyThread("线程E", u, 32);
		MyThread t6 = t.new MyThread("线程F", u, 21);

		t1.start();
		t2.start();
		t3.start();
		t4.start();
		t5.start();
		t6.start();
	}

	class MyThread extends Thread {
		private User u;
		/** 存款金额 */
		private int y = 0;

		public MyThread(String name, User u, int y) {
			super(name);
			this.u = u;
			this.y = y;
		}

		public void run() {
			u.oper(y);
		}
	}

	class User {
		/** 账号 */
		private String code;
		/** 余额 */
		private int cash;

		User(String code, int cash) {
			this.code = code;
			this.cash = cash;
		}

		public String getCode() {
			return code;
		}

		public void setCode(String code) {
			this.code = code;
		}

		/**
		 * 存款
		 * 
		 * @param x
		 *            欲存款金额
		 * 
		 */
		public synchronized void oper(int x) {
			try {
				Thread.sleep(10L);
				this.cash += x;
				System.out.println("线程" + Thread.currentThread().getName()
						+ "运行结束,增加“" + x + "”,当前用户账户余额为:" + cash);
				Thread.sleep(10L);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		@Override
		public String toString() {
			return "User{" + "code='" + code + '\'' + ", cash=" + cash + '}';
		}
	}
}

运行结果:

线程线程A运行结束,增加“20”,当前用户账户余额为:120
线程线程E运行结束,增加“32”,当前用户账户余额为:152
线程线程F运行结束,增加“21”,当前用户账户余额为:173
线程线程D运行结束,增加“-30”,当前用户账户余额为:143
线程线程C运行结束,增加“-80”,当前用户账户余额为:63
线程线程B运行结束,增加“-60”,当前用户账户余额为:3


Java学习笔记---多线程同步的五种方法

一、引言 前几天面试,被大师虐残了,好多基础知识必须得重新拿起来啊。闲话不多说,进入正题。 二、为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会...
  • wenwen091100304
  • wenwen091100304
  • 2015年09月09日 18:33
  • 18671

Java 多线程同步的五种方法

一、为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常。举 个例子,如果一个银行账户同时被两...
  • hard_working1
  • hard_working1
  • 2016年10月08日 21:26
  • 1468

线程同步 各个关键字和方法的使用

1、volatile关键词:用来对共享变量的访问进行同步,上一次写入操作的结果对下一次读取操作是肯定可见的。(在写入volatile变量值之后,CPU缓存中的内容会被写回内存;在读取volatile变...
  • u014201191
  • u014201191
  • 2015年04月15日 10:21
  • 2572

[Java]Java多线程数据安全(同步线程的方法)

预备知识Thread.yield():API中解释: 暂停当前正在执行的线程对象,并执行其他线程。 注意:这里的其他也包含当前线程,即,当前线程也能够再次抢占CPU。Thread.sleep(long...
  • humanking7
  • humanking7
  • 2015年02月05日 23:50
  • 877

c++多线程的创建挂起执行终止 线程间的同步

  • 2012年03月21日 21:36
  • 83KB
  • 下载

【多线程】【同步】【等待唤醒机制】【JDK1.5多线程】【线程优先级&常见方法】

一、多线程基本概念 1、进程:是一个正在执行中的程序。                每一个进程执行都有一个执行的顺序,该顺序是一个执行路径或者叫一个控制单元。 2、线程:就是进程中的一个独立的控制单...
  • mayor125
  • mayor125
  • 2014年09月06日 00:29
  • 839

黑马程序员-多线程(创建线程、方法、同步、通信)总结

---------------------- android培训、java培训、期待与您交流! ---------------------- 一、多线程 进程:运行中的程序; 线程:进程可以有多...
  • huoyun19880910
  • huoyun19880910
  • 2012年08月03日 19:27
  • 766

Java多线程之线程的同步与锁

线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。 例如:1000个Thread都操作同一个对象Counter对象中整型变量count,每次个线程都对count加1。 ...
  • dreamsunday
  • dreamsunday
  • 2018年01月09日 10:56
  • 48

多线程系列二——java线程间的互斥与同步

“线程互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。”   我们可以用银行转账的例子加以说明: 1、甲乙两用户对银行...
  • lyg673770712
  • lyg673770712
  • 2015年09月30日 22:03
  • 637

java多线程之线程并发库的Semaphere同步工具

Semaphore这个东西和之前的synchronized干的事差不多。  synchronized保证了,我管理的那部分代码同一时刻只有一个线程能访问  Semaphore保证了,我管理的那部分...
  • John8169
  • John8169
  • 2016年11月20日 11:02
  • 198
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java多线程-线程的同步(同步方法)
举报原因:
原因补充:

(最多只允许输入30个字)