并发编程基础3

Posted 格物致知

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发编程基础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

 

这次运行结果正确!

以上是关于并发编程基础3的主要内容,如果未能解决你的问题,请参考以下文章

计算机基础了解并发编程

JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段

golang代码片段(摘抄)

Java并发编程系列基础概念

python并发编程之多线程基础知识点

Java并发编程的艺术读书笔记——Java并发编程基础