线程安全的实现方法

一:互斥同步

使用互斥来实现线程间的同步,保证共享数据在同一时刻只被一个线程使用。Java中最基本的互斥手段就是syncrhoized关键字。

syncrhoized的底层原理与操作系统中的信号量的使用类似:编译后,syncrhoized变成两个字节码指令monitorenter和monitorexit,分别位于同步块代码的前后。这两个指令都有一个reference指向锁对象。字节码执行引擎遇到monitorenter时,根据reference获取锁对象,如果能获取,或者当前线程本就获取了这个锁,那么锁的计数器+1;否则等待;当遇到monitorexit时,锁计数器-1;当计数器为0,当前线程释放锁。

二:使用concurrent包实现同步

三:锁的优化

1:自旋锁:当线程申请锁时,锁被占用,则让当前线程执行一个忙循环(自旋),看看持有锁的线程是否会很快释放锁。如果自旋后还没获得锁,才进入同步阻塞状态;

2:自适应自旋:自旋的线程自旋的时间为同一个锁上一次线程自旋并获得锁的耗时。如果对于这个锁,自旋很少有成功的,就不自旋了,避免浪费CPU资源。

3:锁粗化:如果一系列连续操作都对同一对象反复加锁和解锁,甚至加锁解锁出现在循环中,则把锁的同步范围扩大到整个连续序列,进行一次加锁解锁就够了。

4:偏向锁:锁对象偏向于当前获得它的线程,如果在接下来的没有被其他线程请求,则持有该锁的线程将不再需要进行同步操作(即:持有该锁的线程在接下来的执行中遇到同步块时不再需要lock和unlock了,直接执行即可)。当另一个线程申请该锁时,当前线程的偏向模式才会结束,让出该锁。

时间: 2024-08-03 20:25:55

线程安全的实现方法的相关文章

停止Java线程,小心interrupt()方法

程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,将导致意外的行为以及细微的.难以发现的错误. 在本篇文章中,我们针对这些难题之一:如何中断一个正在运行的线程. 背景     中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其当前的操作.线程是死亡.还是等待新的任务或是继续运行至下一步,就取决于这个程序.虽然初次看来它可能显得简单,但是,你必须进行一些预警以实现期望的结果.你最好还是牢记以下的几点告诫. 首先,忘掉

JAVA线程sleep和wait方法区别

一 sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复,调用sleep 不会释放对象锁.由于没有释放对象锁,所以不能调用里面的同步方法. sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用.目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;sleep()是Thread类的Static(静态)的方法:因此他不能改变对象的机锁,所以当在一个Synchronized块

线程管理四种方法

进程:程序在计算机的一次运行活动,一个程序就是一个进程,在iOS中一个app就是一个进程 线程:程序运行的最小单元,一个进程中至少有一个线程(主线程) 一. 通过NSObject的方法管理线程 这种方法会帮助我们自己主动开辟一个后台线程,不须要自己创建 參数:(1)在这个后台线程中运行的方法 參数:(2)用于传递參数,没有为nil [self performSelectorInBackground:@selector(banZhuanPlus) withObject:nil]; } 二.通过NS

C#中跨线程的调用的方法--this.invoke

private void button1_Click(object sender, EventArgs e) { Thread thread = new Thread(new ThreadStart(display)); thread.Start(); } private void display() { while (true) { Thread.Sleep(100); this.Invoke(new threadcall(SetText2)); } } int count = 0; publ

模拟做饭系统(java+线程中的join方法)

(一)项目框架分析 妈妈要去做饭,发现没有酱油,让儿子去买酱油,然后回来做饭. 根据面向对象的思想,有两个对象,妈妈和儿子 主要有两个方法: (一)没有线程控制(即儿子没有买酱油回来妈妈就做好饭了)+(没有调用jion方法) (二)有线程控制(妈妈进程和儿子进程又先后影响)+(调用jion方法) 项目的结构图: (二)没有进程控制mintak Son.java主要是模拟儿子的行动,儿子买酱油的行动(与有进程控制的源程序相同) 代码如下: public class Son implements R

java中创建线程的三种方法以及区别

Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.Java可以用三种方式来创建线程,如下所示: 1)继承Thread类创建线程 2)实现Runnable接口创建线程 3)使用Callable和Future创建线程 下面让我们分别来看看这三种创建线程的方法. ------------------------继承Thread类创建线程--------------------- 通过继承Thread类来创建并启动多线程的一般步骤如下 1]d定义Thread类的子类

java线程Thread的join方法。

1,方法的作用: 父线程等待子线程的执行. 如果是join或者join(0),即等待时长是0,父线程就会一直等到子线程执行结束, 如果是join(time),即等待时长是time数值,那父线程等待时长视情况而定: 第一种:子线程执行时长不需要time时长,那么父线程就可能不会等待到time时长,为什么是可能呢?是不是要考虑其他线程(不包括父线程,和子线程以外的线程),他也可能让父线程等待的(没有获取到cpu时间片等原因), 第二种:子线程执行时长超过time时长,那么父线程的等待时长,至少是ti

【java】终止线程的三种方法

有三种方法可以使终止线程. 1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止. 2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend.resume一样,也可能发生不可预料的结果). 3.  使用interrupt方法中断线程.     1. 使用退出标志终止线程 当run方法执行完后,线程就会退出.但有时run方法是永远不会结束的.如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务.在这种情况下,一般是将这些任务放在一

终止线程的三种方法

有三种方法可以使终止线程. 1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止. 2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend.resume一样,也可能发生不可预料的结果). 3.  使用interrupt方法中断线程. 1. 使用退出标志终止线程 当run方法执行完后,线程就会退出.但有时run方法是永远不会结束的.如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务.在这种情况下,一般是将这些任务放在一个循环中

java线程的几个方法

线程的生命周期:新建状态:用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存 就绪状态:当一个线程创建了以后,其他的线程调用了它的start()方法,该线程就进入了就绪状态.处于这个状态的线程位于可运行池中,等待获得CPU的使用权 运行状态:处于这个状态的线程占用CPU,执行程序的代码 阻塞状态:当线程处于阻塞状态时,java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才有机会转到运行状态. 阻塞状态分为三种情况: 1. 位于对象等待池中的