当前位置:首页 > 开发 > 互联网 > 正文

java 多线程高并发读写控制 误区

发表于: 2015-05-08   作者:qifeifei   来源:转载   浏览:
摘要: 先看一下下面的错误代码,对写加了synchronized控制,保证了写的安全,但是问题在哪里呢? public class testTh7 { private String data; public String read(){ System.out.println(Thread.currentThread().getName() + "read data "

先看一下下面的错误代码,对写加了synchronized控制,保证了写的安全,但是问题在哪里呢?

public class testTh7 {
	private String data;
	public String read(){
		System.out.println(Thread.currentThread().getName() + "read data " + data);
		return this.data;
	}
	public  synchronized void write(String data){
		System.out.println(Thread.currentThread().getName() + " === write data " + data);
		this.data = data;
	}

	public static void main(String[] args) {
		final testTh7 t = new testTh7();
		for (int i = 0; i < 100; i++) {
			if (i % 2 == 0) {
				new Thread(new Runnable() {
					@Override
					public void run() {
						Double d = Math.random();
						t.write(d.toString());
					}
				}).start();
			} else {
				new Thread(new Runnable() {
					@Override
					public void run() {
						t.read();
					}
				}).start();
			}
		}
	}
}

 程序的前部分输出结果如下:

Thread-1read data null

Thread-0 === write data 0.8429852467390618

Thread-2 === write data 0.3111022600208211

Thread-3read data 0.3111022600208211

Thread-4 === write data 0.13391602356879362

Thread-5read data 0.13391602356879362

Thread-8 === write data 0.3014059888796128

Thread-6 === write data 0.7073336550466512

Thread-7read data 0.7073336550466512

Thread-9read data 0.7073336550466512

Thread-10 === write data 0.3157260014049781

Thread-11read data 0.3157260014049781

Thread-15read data 0.3157260014049781

Thread-14 === write data 0.9981422731405993

Thread-16 === write data 0.9011910270245219

Thread-12 === write data 0.34975057489898076

Thread-13read data 0.34975057489898076

Thread-17read data 0.34975057489898076

Thread-18 === write data 0.19089943846264656

Thread-19read data 0.19089943846264656

Thread-21read data 0.19089943846264656

Thread-20 === write data 0.38498810226852065

Thread-22 === write data 0.29234432278529343

Thread-23read data 0.29234432278529343

Thread-27read data 0.29234432278529343

Thread-24 === write data 0.28981062022967496

Thread-29read data 0.28981062022967496

Thread-28 === write data 0.1022791336198855

Thread-26 === write data 0.15466728987586276

Thread-25read data 0.15466728987586276

Thread-31read data 0.15466728987586276

Thread-32 === write data 0.13431233603464776

Thread-33read data 0.13431233603464776

Thread-35read data 0.13431233603464776

Thread-38 === write data 0.33289010029186195

Thread-37read data 0.13431233603464776

Thread-34 === write data 0.5545937895404677

Thread-30 === write data 0.9567137584265717

Thread-36 === write data 0.6461050880921616

 

可以看到Thread-37这行读取的数据已经不正确了,读取的上一次的旧数据,这不是线程安全的缓存设计。首先确认一下原则,只能有一个线程写操作,可以多个线程并发读,但是写时不能读,读时候不能写。

解决办法有多种,可以使用信号量,使用两个信号量,一个是读写的信号量,还有个是写的信号量,如果简单一点,也可以使用java已经封装的读写锁,代码如下,可以自己测试。

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class testReadWrite {

	private String data = null;
	private ReentrantReadWriteLock rw = new ReentrantReadWriteLock();

	public void read() {
		rw.readLock().lock();
		System.out.println(Thread.currentThread().getName() + " read data!");
		System.out.println(Thread.currentThread().getName() + "read data " + data);
		rw.readLock().unlock();
	}

	public void write(String data) {
		rw.writeLock().lock();
		System.out.println(Thread.currentThread().getName() + " ===write data!");
		this.data = data;
		System.out.println(Thread.currentThread().getName() + " ===write data: " + data);
		rw.writeLock().unlock();
	}

}

 

 

java 多线程高并发读写控制 误区

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
Java 提供了语言级别的线程支持,所以在 Java 中使用多线程相对于 C,C++ 来说更简单便捷,但本文并
Java 提供了语言级别的线程支持,所以在 Java 中使用多线程相对于 C,C++ 来说更简单便捷,但本文并
1. 什么是线程 线程是进程内的执行单元 某个进程当中都有若干个线程。 线程是进程内的执行单元。 使
2006 年 8 月 14 日 Java 提供了语言级别的线程支持,所以在 Java 中使用多线程相对于 C,C++ 来说
2006 年 8 月 14 日 Java 提供了语言级别的线程支持,所以在 Java 中使用多线程相对于 C,C++ 来说
2006 年 8 月 14 日 Java 提供了语言级别的线程支持,所以在 Java 中使用多线程相对于 C,C++ 来说
1)由于资源的有限性以及线程之间运行步调的一致性,多个线程在并发执行时,一方面可能会竞争使用同
1)由于资源的有限性以及线程之间运行步调的一致性,多个线程在并发执行时,一方面可能会竞争使用同
1)由于资源的有限性以及线程之间运行步调的一致性,多个线程在并发执行时,一方面可能会竞争使用同
1、多线程优点 资源利用率更好:解决网络IO阻塞问题,能够使CPU在网络IO读取空闲时,处理其他事情
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号