`
cyril0513
  • 浏览: 15695 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

<<并发编程实践>>学习笔记之什么叫锁

 
阅读更多
之前对并发了解的很少,觉得如果程序存在竞争条件,就直接加一个Synchronized就可以解决。发现越多很多源代码之后,发现别人加锁并不是简简单单的在方法上面加一个synchroized这么简单,先上一段代码.
public List<String> lists = Collections
			.synchronizedList(new ArrayList<String>());

	public synchronized boolean listIfAbsent(String str) {
		boolean ifAbsent = lists.contains(str);
		if (!ifAbsent) {
			lists.add(str);
		}
		return ifAbsent;
	}

	public boolean listIfAbsent1(String str) {
		synchronized (lists) {
			boolean ifAbsent = lists.contains(str);
			if (!ifAbsent) {
				lists.add(str);
			}
			return ifAbsent;
		}

	}
       public static void main(String[] args) {
		final Test t = new Test();
		new Thread() {
			public void run() {

				if (!t.lists.contains("a")) {
					t.lists.add("a");
				}
				if (!t.lists.contains("b")) {
					t.lists.add("b");
				}
				// t.lists.set(0, "chenliang");
				System.out.println(t.lists);
			}
		}.start();

		t.listIfAbsent1("a");
		// t.listIfAbsent("b");

	}


这里面有2个方法listIfAbsent和listIfAbsent1,一个应该算是悲观锁,还有一个是只是对list加锁,我之前以为只要对this加锁,该对象的所有的数据域都应该被保护,即使数据域全部被expose,但是经过测试,发现我错了,即使是同样的一个Test对象,当线程A调用listIfAbsent,线程B执行
t.lists.add("a"),这时候发生什么?我之前的理解就是,线程B是不能修改线程list中的数据域的。但事实上,结果并非如此,数据已经被破坏,导致线程会出现过期的数据。
这说明我根本没有理解什么叫锁。
事实上,锁就是对象的一个属性,一个Object对象都有对应的锁属性。我们对Test t这个对象加锁,但是他并不会去检查别的线程是否修改public lists属性。
我的理解就是,加锁的地方只是在方法上,但是这个Test t本身不代表锁。其他的线程仍然可以通过t去访问它其他的共有成员变量,就像这个LIST.如果是多个线程去调用这个上锁的方法的时候,才会出现互斥。
分享到:
评论

相关推荐

    java并发编程实践笔记

    ### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 1. **不要跨线程访问共享变量:** 当多个线程共享某个变量时,若其中一个线程修改了该变量,其他线程若没有正确同步,则可能读取到错误的数据。...

    Java并发编程学习笔记.rar

    这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...

    JAVA并发编程实践-线程池-学习笔记

    Java并发编程实践中的线程池是一个关键的概念,它在多线程编程中扮演着至关重要的角色,有效地管理和调度线程资源,以提高系统的性能和效率。线程池通过复用已存在的线程来减少线程的创建和销毁开销,避免了频繁的上...

    JAVA并发编程实践-构建执行程序块-学习笔记

    JAVA并发编程实践-构建执行程序块-学习笔记 JAVA并发编程实践是指在JAVA编程语言中,使用多线程、并发编程来实现高效、可靠的程序执行。构建执行程序块是指在并发编程中,使用线程安全的类来管理状态,以确保程序的...

    JAVA并发编程实践-线程安全-学习笔记

    在并发编程中,有三种常见的锁策略:乐观锁、悲观锁和自旋锁。乐观锁假设冲突很少发生,因此在读取数据时不加锁,只有在更新时才会检查数据是否被其他线程修改过。悲观锁则假设冲突频繁,所以在读取数据时立即加锁,...

    并发编程之一 日常学习笔记

    本篇将基于"并发编程之一 日常学习笔记"这一主题,深入探讨并发锁机制,特别是对Java中的`synchronized`关键字的深入理解。 并发编程的核心挑战在于正确地管理共享资源,避免数据竞争和死锁等问题。Java的`...

    JAVA并发编程实践-线程执行-学习笔记

    总的来说,Java并发编程实践中的任务执行是一个涉及线程调度、线程池管理、任务生命周期控制、结果处理等多个方面的复杂主题。理解和掌握这些概念和技术,能够帮助开发者编写出更加高效、可靠的并发程序。

    GoLang学习资源_学习笔记和并发编程实战

    通过阅读"Go语言学习笔记",你可以建立起对Go语言全面的认知,然后借助"Go并发编程实战"来深化对并发编程的理解,结合实际编写示例程序,将理论知识转化为实践经验。 在学习过程中,建议先从基础语法开始,掌握变量...

    <<JAVA学习笔记>>实例源代码

    本压缩包中包含的"Example"文件夹,极有可能是《JAVA学习笔记》一书中的实例源代码,旨在帮助读者深入理解书中讲解的Java编程原理和实践技巧。下面我们将对这些源代码进行详细解读,以便更好地掌握Java编程。 1. **...

    <<MFC深入浅出>>(中文简体)

    MFC的DLL支持可以帮助减少程序的内存占用,ActiveX控件则允许开发可重用的组件,多线程则可以实现并发执行,提升程序响应速度。 通过阅读《MFC深入浅出》,读者不仅可以掌握MFC的基本用法,还能了解到许多实际开发...

    JUC并发编程学习笔记(硅谷)

    "JUC并发编程学习笔记(硅谷)"很可能包含了关于Java并发工具集(Java Util Concurrency, JUC)的深入理解和实战经验。JUC是Java标准库提供的一套强大的并发处理工具,它极大地简化了多线程编程,提高了程序的可读性...

    Java并发实践-学习笔记

    11. **案例分析与实战**:笔记可能包含实际的并发编程案例,帮助读者更好地将理论知识应用到实践中。 通过深入学习这份"Java并发实践-学习笔记",开发者能够提升自己在处理多线程和并发问题上的能力,从而设计出更...

    多线程与高并发编程笔记、源码等

    标题“多线程与高并发编程笔记、源码等”表明了资源的核心内容,涵盖了多线程和高并发编程的理论与实践。多线程允许一个应用程序同时执行多个任务,而高并发则指系统能够处理大量并发请求的能力。这两个概念在现代...

    JAVA并发编程实践-线程的关闭与取消-学习笔记

    在Java并发编程中,线程的关闭和取消是一项重要的任务,因为不正确的处理可能导致数据不一致、资源泄漏等问题。在Java中,强制停止线程并不是一个推荐的做法,因为这可能会导致系统状态的不稳定。传统的`Thread.stop...

    JAVA并发编程实践-线程对象与组合对象-学习笔记

    使用java.util.concurrent类库构造安全的并发应用程序的基础。共享其实就是某一线程的数据改变对其它线程可见,否则就会出现脏数据。

    C++学习笔记.doc

    - 并发编程:学习多线程和并发控制,提高程序效率。 - 高级特性:如Lambda表达式、右值引用、自动类型推断(auto)等现代C++特性。 **四、C++的实践** 理论学习是基础,但实践才能真正巩固知识。通过编写小程序、...

    并发编程笔记+包含所有

    本笔记主要聚焦于Java平台上的并发编程,旨在帮助开发者理解和掌握相关的核心概念、工具和最佳实践。 一、线程与进程 在并发编程中,我们首先需要理解“线程”和“进程”的概念。进程是操作系统分配资源的基本单位...

    并发编程笔记(httpswww.bilibili.comvideoav84491203p=279).zip

    **并发编程笔记** 在计算机科学中,并发编程是让多个任务在同一时间运行的技术,它可以显著提升系统的效率和响应性。特别是在多核处理器和分布式系统中,并发编程是必不可少的技能。本笔记主要针对Java平台,深入...

Global site tag (gtag.js) - Google Analytics