`

线程安全扫盲贴一——什么是线程安全

阅读更多

线程的系统都写完了,遇到很多问题,刚开始写到处都在synchronized,跌倒又爬起来,现在回过头来看看JAVA并发实践,开始整理下。

 

《JAVA并发编程实践》说线程安全就是,在单线程执行时候,实例状态是正确的,在多线程执行的时候,状态仍要正确:

a class is thread-safe when it continues to behave correctly when accessed
from multiple threads.

 

下面这段代码,如果在单线程下,Counter的状态(由count来表示其状态)应该是从1、2、3.。。。20.

并发后状态就坏掉了,这就是按他定义的线程不安全:

如在run方法中调用Counter类的increase和increase2方法,他们是线程安全的,输出都是0、1、2、3.。。。

而increase3则是:0 1 1 2 4 5 6 7 8 9 10 11 12 13 14 15 16 16 18 19

 

 

package com.zyp.test.concurrent;

public class Counter {
	private int count = 0;
	public int increase(){
		synchronized (this) {
			System.out.print(count+" ");
			return count++;
		}
	}
	public synchronized int increase2(){
		System.out.print(count+" ");
		return count++;
	}
	public int increase3(){
		System.out.print(count+" ");
		return count++;
	}
	public int getCount() {
		return count;
	}
}
 
package com.zyp.test.concurrent.thread;

import com.zyp.test.concurrent.Counter;

public class CounterThread extends Thread{
	private Counter counter;
	public CounterThread(Counter counter){
		this.counter = counter;
	}
	
	public void run(){
		//此处测试三种increase方法
		counter.increase();
//		counter.increase2();
//		counter.increase3();
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
	
	public static void main(String[] args){
		Counter counter = new Counter();
		for(int i = 0;i<20;i++){
			CounterThread t = new CounterThread(counter);
			t.start();
			if(i%3==0){
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

 

 

由于内部锁是基于线程而非调用的,当一个线程执行increase方法时,已经拿到了counter对象引用的锁,那么其他线程执行执行同一个counter对象的increase或increase2会堵塞等待counter对象锁。

 

按《JAVA并发编程实践》里面的建议是,如果状态变量会被一个线程修改,那么所有其他访问(access)该状态变量的线程访问时都要同步。(包括读操作)

 

 

******************

摘录一点《JAVA并发编程实践》:

Whenever more than one thread accesses a given state variable, and one of them might
write to it, they all must coordinate their access to it using synchronization.

无论何时有多个线程要访问一个状态变量(实例的成员变量),其中有一个线程可能会写状态变量的值,那么所有线程必须通过同步来协调他们对状态变量的访问。

 

No set of operations performed sequentially or concurrently on instances of a thread-safe class can cause an instance to be in an invalid state。

顺序执行的一组操作或在线程安全的类的多个实例上并发执行的操作,将不会造成实例的状态变量不正确。

 

分享到:
评论

相关推荐

    线程,同步与锁————Lock你到底锁住了谁?.htm

    线程,同步与锁————Lock你到底锁住了谁?.htm

    mysql是线程不安全的,mysql不是线程安全的,多线程共用同一个mysql连接是会崩溃的.所以同样QT的QSqlDatabase也是线程不安全的,QS会崩溃

    mysql是线程不安全的,mysql不是线程安全的,多线程共用同一个mysql连接是会崩溃的 QT的QSqlDatabase是基于mysql的,所以一样是线程不安全的 现讲明mysql为什么是线程不安全的,以及在多线程环境下如何使用mysql,...

    并发编程——认识java里的线程(csdn)————程序.pdf

    并发编程——认识 Java 里面的线程 在 Java 编程中,并发编程是一个非常重要的概念。Java 程序天生就是多线程的,main 方法开始执行后,按照既定的代码逻辑执行,看似没有其他线程参与,但实际上 Java 程序天生就是...

    C#多线程List的非线程安全性

    在C#编程中,多线程环境下的数据操作是一个复杂且需要谨慎处理的领域。本文将深入探讨在多线程环境中使用List时遇到的非线程安全问题,并提供相应的解决方案和最佳实践。 List是.NET框架中常用的一个动态数组,它...

    关于如何解决HashMap线程安全问题的介绍

    2. 使用ConcurrentHashMap:Java从1.5版本开始引入了ConcurrentHashMap,它是线程安全且高并发性能的替代方案。ConcurrentHashMap通过分段锁机制实现并发控制,相比于synchronized Map,其在高并发环境下有更好的...

    c# 线程安全队列的用法原理及使用示例

    什么是线程安全? 答:线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等...

    CVI 线程锁、线程安全变量实例

    线程安全变量,另一方面,是指可以在多线程环境中安全使用的变量。这类变量的修改和访问都是原子操作,不会因线程切换而引发问题。在LabWindows/CVI中,实现线程安全变量可能需要使用特定的线程库函数,如`...

    python进程、线程(csdn)————程序.pdf

    线程池与进程池类似,但是它是线程的集合。在Python中,`concurrent.futures`模块提供了`ThreadPoolExecutor`类,可以预先创建一组线程,然后提交任务给这些线程。这种方式可以有效地控制线程数量,避免过多线程导致...

    浅谈C#跨线程调用窗体控件(比如TextBox)引发的线程安全问题

    C#跨线程调用窗体控件时可能会引发线程安全问题,例如当多个线程操作同一个控件时,该控件可能会进入不一致的状态,出现争用情况和死锁等问题。因此,确保以线程安全方式访问控件非常重要。 在C#中,控件并不是线程...

    多线程编程之一——问题提出

    ### 多线程编程之一——问题提出 在深入探讨多线程编程的复杂性和优势之前,我们首先需要明确为何要采用多线程编程,以及它所解决的问题是什么。多线程编程是现代软件开发中不可或缺的一部分,尤其是在高性能计算、...

    多线程测试(wxWidgets)

    首先,我们要理解什么是线程。线程是操作系统分配CPU时间的基本单位,每个线程都有自己的执行上下文,包括程序计数器、栈和局部变量。一个进程可以包含一个或多个线程,共享同一块内存空间,这样就实现了数据的快速...

    多线程编程之三——线程间通讯

    在某些编程语言(如Go)中,通道是一种内建的线程间通信机制,允许数据在两个线程间安全地传递。 7. 使用队列(Queue) 线程间可以共享一个队列,一个线程生产数据,另一个线程消费数据。这种方法需要配合同步原语...

    Java多线程之定时任务 以及 SpringBoot多线程实现定时任务——异步任务

    1. SpringBoot 自定义线程池以及多线程间的异步调用(@Async、@EnableAsync) 2.Java多线程之定时任务 以及 SpringBoot多线程实现定时任务 3.@EnableScheduling 与 @Scheduled

    C# 高效线程安全,解决多线程写txt日志类.zip

    首先,我们要理解什么是线程安全。线程安全是指当多个线程同时访问一个对象或方法时,代码仍然能够正确执行,不会出现数据混乱或者异常的情况。在C#中,实现线程安全通常有几种策略:锁(Lock)、Monitor、Mutex、...

    c++11 多线程编程——如何实现线程安全队列

    线程安全队列的接口文件如下: #include template class threadsafe_queue { public: threadsafe_queue(); threadsafe_queue(const threadsafe_queue&); threadsafe_queue& operator=(const threadsafe_queue&...

    易语言线程安全之原子锁与读写锁

    在IT行业中,线程安全是多线程编程中的一个重要概念,确保多个线程并发执行时,数据的正确性和完整性不会受到影响。线程安全通常通过同步机制来实现,其中包括原子操作和锁机制。本文将深入探讨易语言中的原子锁与...

    C# 高效线程安全,解决多线程写txt日志类

    在C#编程中,线程安全是多线程应用程序中至关重要的一个方面,尤其是在处理共享资源如文本日志文件时。本主题将深入探讨如何在C#中创建一个高效的线程安全日志类,用于在多线程环境中安全地写入txt日志。 首先,...

    Java多线程的小例子——吃包子

    这个名为"Java多线程的小例子——吃包子"的示例,旨在帮助开发者直观地理解多线程的工作原理。下面我们将深入探讨该示例所涉及的核心知识点。 首先,多线程通常涉及到以下几个关键概念: 1. **线程(Thread)**:...

Global site tag (gtag.js) - Google Analytics