先看一下下面的错误代码,对写加了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
本文将围绕“Java多线程高并发相关资料收集”这一主题,详细探讨这两个领域的核心知识点。 首先,多线程是指在单个程序中同时执行多个线程。Java提供了一个强大的多线程支持,允许开发者创建、管理和控制多个执行...
在并发控制中,我们通常会遇到以下几个关键概念: - 同步:确保同一时间只有一个线程访问共享资源,防止数据不一致。Java提供了synchronized关键字以及Lock接口(如ReentrantLock)来实现同步。 - volatile:修饰...
在Java多线程高并发编程中,重入锁(ReentrantLock)是一个至关重要的概念,它提供了比Java内置锁(synchronized)更细粒度的控制,并且具有更高的可读性和可扩展性。本篇文章将深入探讨重入锁的相关知识点。 首先...
Java多线程与并发编程是Java语言中用于处理多任务执行的关键技术,它能够帮助开发者设计出能够有效应对高并发请求的应用程序。在现代的线上(Online)和离线(Offline)应用中,合理利用多线程技术可以大幅提高系统...
张孝祥Java多线程与并发库高级应用学习笔记,很经典的学习多线程和并发的资料。张孝祥Java多线程讲义笔记由张孝祥亲自整理,很实用的。
资源名称:Java多线程与并发库高级应用视频教程22集资源目录:【】01传统线程技术回顾【】02传统定时器技术回顾【】03传统线程互斥技术【】04传统线程同步通信技术【】04传统线程同步通信技术_分割纪录【】05线程...
Java多线程与并发编程是Java开发中至关重要的一部分,它涉及到如何高效地利用CPU资源,以实现程序的并行执行。在操作系统层面,多任务和多进程是通过分配不同的内存空间来实现的,而线程则共享同一进程的内存,这...
java多线程并发的在新窗口
通过分析和运行这些代码,你将能够更深入地理解Java多线程在高并发场景下的实际运用,从而在你的人工智能项目中实现更高效、更稳定的数据处理。 总之,这个项目实例旨在帮助开发者掌握Java多线程技术,提升处理高...
在IT领域,多线程和高并发是两个关键概念,特别是在Java编程中,它们对于构建高效、可扩展的系统至关重要。下面将详细解释这两个概念及其在Java中的实现和应用。 多线程是指在一个应用程序中同时运行多个独立的执行...
黑马+传智 Java入门到精通视频教程+课件+代码,30套Java开发项目代码,Java多线程与并发库高级应用视频教程,及电子书,面试题,开发工具等
Java 高并发多线程编程系列案例代码 & 教程 & 面试题集锦! !! 包括但不限于线程安全性, atomic包下相关类、CAS原理、Unsafe类、synchronized关键字等的使用及注意事项,
多线程并发控制是解决高并发问题的关键技术。Java提供了丰富的线程API,如Thread、Runnable接口,以及同步机制如synchronized关键字、Lock接口(如ReentrantLock)等。在设计多线程程序时,需要注意资源的竞争和死锁...
根据给定文件的信息,我们可以提炼出以下关于Java多线程与并发库的相关知识点: ### Java多线程基础 1. **线程的概念**:在Java中,线程是程序执行流的基本单元。一个标准的Java应用程序至少有一个线程,即主...
在深入探讨Java多线程与并发库的高级应用前,有必要了解一些基础概念。Java线程是Java程序的基础,它代表程序中的一条执行线索或线路。在Java中创建线程有两种传统方式,一种是通过继承Thread类并覆盖其run方法来...
综上所述,"java多线程查询数据库"是一个涉及多线程技术、线程池管理、并发控制、分页查询等多个方面的复杂问题。通过理解和掌握这些知识点,我们可以有效地提高数据库操作的效率和系统的响应速度。
Java多线程与并发编程是Java开发中不可或缺的一部分,它涉及到如何高效地利用CPU资源,实现并发执行多个任务。在操作系统层面,多线程是为了提高系统利用率,使得多个任务能够"同时"执行,但实际上,由于CPU的时钟...
Java多线程读大文件 java多线程写文件:多线程往队列中写入数据