并发编程基础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
这次运行结果正确!