并发编程基础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应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段