`

线程 多线程同步加锁说明

 
阅读更多

 

 

看代码,看注释,

一般都是用 synchronized(this){  代码块 }, 其中注意体会this到底代表的是谁, 并注意 加锁的代码块的范围别太小造成跑出的数据异常。

 

 

 

 

 

public class SynDemo01 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//真实角色
		Web12306 web= new Web12306();
		//代理, 这两个代理都是针对 同一个真实对象 web 进行操作的,这样在 synchronized(this)的时候才会保证加锁正确。
		Thread t1 =new Thread(web,"zhangsan");
		Thread t2 =new Thread(web,"lisi");
		//启动线程
		t1.start();
		t2.start();

	}

}


/**
 * 线程安全的类   线程安全 需要等待 这就是效率低的说法的来源 
   加锁下,范围不能太大 太大效率低  太小锁不正确 , 并且加锁对象也要对,否则达不到加锁目的
 * @author Administrator
 *
 */
class Web12306 implements Runnable {
	private int num =10;
	private boolean flag =true;
	@Override
	public void run() {
		while(flag){
			test5();
		}
	}
	// 加锁范围太小 造成数据异常
    // 跑出结果中 有 lisi抢到了-1
	public void test6(){
	   	
		if(num<=0){
			flag=false; //跳出循环
			return ;
		}
		 //a  b  c 	
		synchronized(this){  //  
			try {
				Thread.sleep(500); //模拟 延时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
	
	//线程不安全  锁定资源不正确
    	/**
lisi抢到票了,还剩下 0 张
zhagnsan抢到票了,还剩下 0 张
	 */
	public void test5(){
		//a  b  c
		synchronized((Integer)num){// 锁错对象了   一般锁定最多的还是锁对象 
			if(num<=0){
				flag=false; //跳出循环
				return ;
			}
			try {
				Thread.sleep(500); //模拟 延时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
	
	
	
	//锁定范围不正确 线程不安全
    /**
	 * zhagnsan抢到票了,还剩下 -1 张
	 */
	public void test4(){
		//   c  1
		synchronized(this){
			//b
			if(num<=0){
				flag=false; //跳出循环
				return ;
			}
		}
		// b
		try {
			Thread.sleep(500); //模拟 延时
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
	}//a -->1
	
	
	
	//线程安全  锁定正确
	public void test3(){
		//a  b  c
		synchronized(this){// this 表示这份资源,  只有多个线程在使用 同一个Web12306类的对象时,才会进行加锁,eg:线程1 线程2 同时操作Web12306类的对象1,这两个线程在抢夺ticket时,哪个线程先进来就加锁
			if(num<=0){
				flag=false; //跳出循环
				return ;
			}
			try {
				Thread.sleep(500); //模拟 延时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
	//线程安全  锁定正确
	public synchronized void test2(){
		if(num<=0){
			flag=false; //跳出循环
			return ;
		}
		try {
			Thread.sleep(500); //模拟 延时
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
	}
	
	
	//线程不安全
    	/**
	lisi抢到票了,还剩下 0 张
	zhagnsan抢到票了,还剩下 -1 张
	lisi抢到票了,还剩下 -2 张
	 */
	public void test1(){
		if(num<=0){
			flag=false; //跳出循环
			return ;
		}
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
	}
}

 

  • 大小: 39.2 KB
分享到:
评论

相关推荐

    windowsC++多线程加锁信号量共享内存

    然而,多线程编程也带来了一些挑战,如数据竞争和死锁问题,这些问题需要通过同步机制来解决。在这个场景下,"windowsC++多线程加锁信号量共享内存"就是我们要探讨的核心主题。 首先,让我们了解什么是多线程。多...

    freelockqueue(多线程不需要加锁的队列性能很高)

    为了解决这个问题,"freelockqueue"应运而生,它提供了一种无需加锁的多线程队列实现,从而显著提升了程序的运行效率。 无锁队列的核心思想是利用原子操作(如Interlocked类提供的操作)以及硬件级别的内存模型来...

    Qt两种方法实现多线程并安全结束线程及QMutex加锁Qt单例化实现

    在Qt框架中,多线程的应用是常见的性能优化手段,特别是在UI更新和后台处理分离时。本主题将详细探讨如何使用Qt的QThread类来创建和管理线程,并且安全地结束线程,同时结合QMutex进行线程同步,以及如何实现Qt的...

    Python多线程编程之多线程加锁操作示例

    在Python中,还有其他同步原语,如条件变量(Condition)、信号量(Semaphore)、事件(Event)等,它们在多线程编程中也有各自的用途。在实际应用中,根据需求选择合适的同步机制可以有效管理资源,避免竞态条件,...

    c++线程加锁

    在多线程编程中,确保线程安全是至关重要的,特别是在共享数据的访问上。C++线程加锁机制提供了一种方式来防止多个线程同时访问临界资源,从而避免数据竞争和不一致的问题。在给定的描述中,我们看到通过Windows API...

    C#代码_线程同步线程同步线程同步线程同步线程同步线程同步

    在C#中,线程同步可以通过多种机制来实现,其中包括信号量(Semaphore)和加锁机制。本文将深入探讨这些知识点,并通过一个名为`Semaphore_Demo`的代码示例进行说明。 一、线程同步的重要性 在多线程环境下,当多个...

    NET面试题-多线程编程与线程同步1

    【描述】:本篇文章主要探讨.NET框架下的多线程编程与线程同步相关的面试问题,包括线程与进程的区别、GUI线程访问控件限制、后台线程与前台线程、锁的使用以及线程同步的不同策略。 【标签】:“软件/插件”、...

    QT单例模式、多线程、双重校验加锁

    在QT中,单例模式、多线程以及双重校验加锁(Double-Checked Locking)是常见的编程模式和技术,尤其在处理并发和资源管理时显得尤为重要。 **单例模式** 是一种设计模式,确保一个类只有一个实例,并提供一个全局...

    C#实现多线程同步并发操作

    本文将深入探讨如何在C#中实现多线程同步并发操作,这不仅对于提高软件性能至关重要,也是高级程序员必须掌握的核心技能之一。 ### C#中的多线程同步并发操作 多线程编程可以极大地提高CPU的利用率,特别是在处理I...

    python多线程同步之文件读写控制

    在Python编程中,多线程同步对于文件读写控制至关重要,因为如果不加以控制,多个线程同时访问同一文件可能会导致数据不一致或者错误。这里我们将深入探讨如何在Python中使用多线程同步来确保文件读写的安全性。 ...

    QT中sqlite多线程操作4个注意问题

    然而,当在多线程环境中使用SQLite时,需要注意一些关键问题以确保数据的安全性和一致性。以下是四个重要的考虑因素: 1. **线程安全**: SQLite本身并不提供完全的线程安全,这意味着在不同线程中并发访问数据库...

    python多线程编程示例(threading.py)

    Unix调度较快),缺点是线程之间的同步和加锁比较麻烦。 2、Python多线程创建 在Python中,同样可以实现多线程,有两个标准模块thread和threading,不过我们主要使用 更高级的threading模块。

    多线程文件加锁自动定时查询mysql统计数据

    在多线程环境下,需要注意线程同步和互斥问题,以防止数据竞争和不一致。 2. **文件加锁**: 文件加锁是一种机制,用于在多线程或多进程环境中保护共享资源,防止同时修改同一文件引发的数据冲突。在Unix/Linux...

    java 多线程同步方法的实例

    在Java编程语言中,多线程同步是一种控制多个线程并发执行的重要机制,它确保了共享资源的安全访问,防止数据不一致性和竞态条件的发生。本文将深入探讨Java中的多线程同步方法,并通过实例来阐述其工作原理。 首先...

    Linux系统下的多线程编程入门.pdf

    本文将深入探讨Linux环境中的多线程概念、创建与管理线程的方法、线程同步与通信机制,以及多线程编程中可能遇到的问题和解决策略。 一、多线程概念 多线程是指在一个进程中可以同时执行多个独立的代码段,每个代码...

    Python 多线程不加锁分块读取文件的方法

    ### Python多线程不加锁分块读取文件的方法 #### 概述 在进行文件处理时,特别是在处理大型文件时,使用多线程技术能够显著提高程序的执行效率。然而,多线程环境下文件的读取操作如果不加以适当管理,则可能会...

    delphi多线程调用dll

    当需要在多线程环境中调用DLL时,情况会变得相对复杂,因为线程安全、资源管理以及同步问题需要额外的关注。 首先,我们需要理解多线程的基本概念。在Delphi中,我们可以使用TThread类来创建和管理线程。每个线程都...

Global site tag (gtag.js) - Google Analytics