并发编程基础3

一:脏读,对于数据的读取没有做到一致性,正如下面的例子,两个线程同时操作一个对象,一个线程设置对象的值,

另一个线程读取对象的值,但是在第一个线程没有设置完成时(业务逻辑处理时间比较长),第二个线程就开始获取
数据了,所以会出现问题。

/**
 * 
 */
package com.day2;

/**
 * @author Administrator
 * 脏读,对于数据的读取没有做到一直性,正如下面的例子,两个线程同时操作一个对象,一个线程设置对象的值,
 * 另一个线程读取对象的值,但是在第一个线程没有设置完成时(业务逻辑处理时间比较长),第二个线程就开始获取
 * 数据了,所以会出现问题。
 */
public class MutiThread {

	private String username = "root";
	private String password = "1234";

	public synchronized void setValue(String username, String password) {
		this.username = username;
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		this.password = password;
		System.out.println("最终结果:用户名" + this.username + "密码:" + this.password);
	}

	public  void getValue() {
		System.out.println("获取结果:用户名" + this.username + "密码:" + this.password);
	}

	public static void main(String[] args) {
		final MutiThread task = new MutiThread();
		// 线程1set数据
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				task.setValue("mysql", "4567");
			}
		});
		t1.start();
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		task.getValue();
	}
}

  

运行结果:

获取结果:用户名mysql密码:1234
最终结果:用户名mysql密码:4567

 

出现错误,实际上想获取的是最终结果,但是由于setValue()处理逻辑时间比较长,这个时候就来获取值getValue(),

所以出现错误,为了避免这种情况,对于相同的业务,set与get应该做到同步,都加上synchronized锁

public synchronized void setValue(String username, String password) {
		this.username = username;
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		this.password = password;
		System.out.println("最终结果:用户名" + this.username + "密码:" + this.password);
	}

	public synchronized void getValue() {
		System.out.println("获取结果:用户名" + this.username + "密码:" + this.password);
	}

  

运行结果:

最终结果:用户名mysql密码:4567
获取结果:用户名mysql密码:4567

 

这次运行结果正确!

posted @ 2017-07-18 22:33  程序员三藏  阅读(211)  评论(0编辑  收藏  举报