Java多线程

您所在的位置:网站首页 get到了怎么读 Java多线程

Java多线程

2024-06-02 12:57| 来源: 网络整理| 查看: 265

Java多线程——深入理解"脏读"

  脏读:某线程取到的数据是被其他线程所修改过的。

  在Java中,若没有使用加锁操作,所有的线程之间是异步执行的,因此就会产生"脏读"导致数据的丢失或错误。   首先来看根本没有任何加锁操作的情况。 class MyThread implements Runnable{ private int num = 5; @Override public void run() { showNum(); } public void showNum(){ while (num>0){ num--; System.out.println(Thread.currentThread().getName()+":"+num); } } } public class DirtyReadTest { public static void main(String[] args) { MyThread myThread = new MyThread(); new Thread(myThread,"A").start(); new Thread(myThread,"B").start(); } } // 执行结果 B:3 A:3 A:2 A:1 A:0

  程序解读:从这个执行结果可以看出,A:3并且B:3,同一个3出现了两次,明显与逻辑不符,出现了"脏读"。

  此时需要给该方法加上synchronized关键字,从而保证一次只会有一个线程进入该方法,保证同步即线程安全。 public synchronized void showNum(){ while (num>0){ num--; System.out.println(Thread.currentThread().getName()+":"+num); } } // 执行结果 A:4 A:3 A:2 A:1 A:0

  程序解读:此时线程A始终拥有该对象的锁,由于线程A和线程B都是在调用对象MyThread,因此A反复进行打印知道num=-1,而当A释放锁后,B获取到锁,此时第一次判断num>0的结果就是false,while循环不会进入,程序执行结束。

  现在就产生一个疑惑,有了synchronized关键字修饰真的就完全保证了同步吗?   实际上与程序是如何编写的有很大的关系,举个栗子: class PublicVar{ private String username = "A"; private String password = "AA"; public synchronized void setValue(String username,String password){ try { this.username = username; Thread.sleep(5000); this.password = password; System.out.println("setValue method thread name=" +Thread.currentThread().getName()+" username=" +username+" password="+password); } catch (InterruptedException e) { e.printStackTrace(); } } public void getValue(){ System.out.println("getValue method thread name=" +Thread.currentThread().getName()+" username=" +username+" password="+password); } } class ThreadA extends Thread{ PublicVar publicVar = null; public ThreadA(PublicVar publicVar) { this.publicVar = publicVar; } @Override public void run() { publicVar.setValue("B","BB"); } } public class DirtyReadTest2 { public static void main(String[] args) { try { PublicVar publicVar = new PublicVar(); ThreadA threadA = new ThreadA(publicVar); threadA.start(); // 程序的结果与这个睡眠时间相关 // 此处的睡眠时间>setValue()中的睡眠时间: 等设置完值后才取得值,不会出现脏读。 // 此处的睡眠时间


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3