一.为什么要线程同步

因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常。
举个例子,如果一个银行账户同时被两个线程操作,一个取100块,一个存钱100块。假设账户原本有0块,如果取钱线程和存钱线程同时发生,会出现什么结果呢?取钱不成功,账户余额是100.取钱成功了,账户余额是0.那到底是哪个呢?很难说清楚。因此多线程同步就是要解决这个问题。

不同步时的代码  抛出混乱问题,使用同步时的代码会保证多个线程有条不紊的执行,保证结果正确一致

二.多线程同步运行的5种办法:

(1)同步方法: 用synchronized关键字修饰方法。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

(2)同步代码块  即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步

注:同步是一种高开销的操作,因此应该尽量减少同步的内容。通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。

(3)特殊域变量(volatile)

a.volatile关键字为域变量的访问提供了一种免锁机制
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量
是不是又看不懂了,又乱了。这是为什么呢?就是因为volatile不能保证原子操作导致的,因此volatile不能代替synchronized。此外volatile会组织编译器对代码优化,因此能不使用它就不适用它吧。 它的原理是每次要线程要访问volatile修饰的变量时都是从内存中读取,而不是存缓存当中读取,因此每个线程访问到的变量值都是一样的。这样就保证了同步。

(4)重入锁(ReentrantLock ) 在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。ReentrantLock类是可重入、互斥、实现了Lock接口的锁, 它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。

ReenreantLock类的常用方法有:
        ReentrantLock() : 创建一个ReentrantLock实例
        lock() : 获得锁
        unlock() : 释放锁
注:ReentrantLock()还有一个可以创建公平锁的构造方法,但由于能大幅度降低程序运行效率,不推荐使用

(5)使用线程局部管理ThreadLocal   存在问题!

ThreadLocal的原理:
如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变 量副本,而不会对其他线程产生影响。
即每个线程运行的都是一个副本,也就是说存钱和取钱是两个账户,只是名字相同而已,两个线程间的count没有关系。所以就会发生上面的效果。
 
ThreadLocal与同步机制
a.ThreadLocal与同步机制都是为了解决多线程中相同变量的访问冲突问题
b.前者采用以”空间换时间”的方法,后者采用以”时间换空间”的方式
 
ThreadLocal并不能替代同步机制,两者面向的问题领域不同。
1:同步机制是为了同步多个线程对相同资源的并发访问,是为了多个线程之间进行通信的有效方式;
2:而threadLocal是隔离多个线程的数据共享,从根本上就不在多个线程之间共享变量,这样当然不需要对多个线程进行同步了。
 
 参考来源:
 

java多线程同步的5种方法的更多相关文章

  1. Java 多线程同步的五种方法

    一.引言 闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子 ...

  2. JAVA多线程实现的三种方法

    JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...

  3. Java中实现线程同步的三种方法

    实现同步的三种方法 多线程共享数据时,会发生线程不安全的情况,多线程共享数据必须同步. 实现同步的三种方法: 使用同步代码块 使用同步方法 使用互斥锁ReetrantLock(更灵活的代码控制) 代码 ...

  4. Java多线程同步问题的探究

    一.线程的先来后到——问题的提出:为什么要有多线程同步?Java多线程同步的机制是什么? http://www.blogjava.net/zhangwei217245/archive/2010/03/ ...

  5. java多线程同步

    一篇好文:java多线程机制同步原则 概括起来说,Java 多线程同步机制主要包含如下几点:1:如果一个类包含一个或几个同步方法,那么由此类生成的每一个对象都配备一个队列用来容纳那些等待执行同步的线程 ...

  6. (转)Java结束线程的三种方法

    背景:面试过程中问到结束线程的方法和线程池shutdown shutdownnow区别以及底层的实现,当时答的并不好. Java结束线程的三种方法 线程属于一次性消耗品,在执行完run()方法之后线程 ...

  7. java多线程中的三种特性

    java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...

  8. JAVA实现单例模式的四种方法和一些特点

    JAVA实现单例模式的四种方法和一些特点,需要的朋友可以参考一下     一.饿汉式单例类 复制代码 代码如下: public class Singleton  {      private Sing ...

  9. Java多线程同步和异步问题

    我们首先来说一下多线程: 多线程很形象的例子就是:在一个时刻下,一个班级的学生有人在拖地,有人在擦窗户,有人在擦桌子 按照单线程程序,肯定是先去拖地,再去擦窗户,再去擦桌子.但是在多线程就好像他们在一 ...

随机推荐

  1. Apache OfBiz 反序列化命令执行漏洞(CVE-2020-9496)

    影响版本 - Apache Ofbiz:< 17.12.04 访问 https://192.168.49.2:8443/webtools/control/xmlrpc 抓包 进行数据包修改 pa ...

  2. tensorflow踩坑合集2. TF Serving & gRPC 踩坑

    这一章我们借着之前的NER的模型聊聊tensorflow serving,以及gRPC调用要注意的点.以下代码为了方便理解做了简化,完整代码详见Github-ChineseNER ,里面提供了训练好的 ...

  3. 一文彻底搞清 Gradle 依赖【转】

    来源:曾是放牛娃 www.jianshu.com/p/59fd653a54d2 转自:https://mp.weixin.qq.com/s?__biz=MzA3MDMyMjkzNg==&mid ...

  4. 做了两年多的安卓,突然想转Java后端,感觉Android职业前景不太好,转还是不转?

    近几年相信很多Android开发者都有过这种想法,最终还是有些Android 开发选择了转行,但是还有些开发者选择了坚持. 因为现在Android开发确实竞争很大,很多公司抛出几个岗位,每天能收到成百 ...

  5. 线程礼让_yield

    线程礼让_yield 礼让线程,让当前正在执行的线程暂停,但不阻塞 将线程从运行状态转为就绪状态 让cpu重新调度,礼让不一定成功!看CPU心情 测试案例: package multithreadin ...

  6. Java多线程操作同一个对象,线程不安全

    Java多线程操作同一个对象 发现问题:多个线程操作同一资源的情况下,线程不安全,数据紊乱 代码: package multithreading; // Java多线程操作同一个对象 // 买火车票的 ...

  7. 『Java』数组

    在学习数组之前先学习java.util.Arrays类中的一个静态方法Arrays.toString(). 该方法可以将传入的数组格式化为一个字符串,便于我们查看数组内容,例如: import jav ...

  8. 1051 Pop Sequence (25分)栈

    刷题 题意:栈的容量是5,从1~7这7个数字,写5个测试数据 做法:模拟栈 #include<bits/stdc++.h> using namespace std; const int m ...

  9. MySQL-04-SQL简单介绍

    SQL介绍 SQL 结构化查询语言 5.7 以后符合SQL92严格模式 通过sql_mode参数来控制 常用SQL分类 DDL:数据定义语言 DCL:数据控制语言 DML:数据操作语言 DQL:数据的 ...

  10. 【笔记】多项式回归的思想以及在sklearn中使用多项式回归和pipeline

    多项式回归以及在sklearn中使用多项式回归和pipeline 多项式回归 线性回归法有一个很大的局限性,就是假设数据背后是存在线性关系的,但是实际上,具有线性关系的数据集是相对来说比较少的,更多时 ...