精华内容
下载资源
问答
  • 如何解决并发

    2016-09-22 18:03:49
    并发产生的原因虽然从宏观上,处理器是并行处理多项任务,但本质上一个处理器在某个时间点只能处理一个任务,属于串行执行。在单处理器的情况下,并发问题源于多道程序设计系统的一个基本特性:进程的相对执行速度不...

    并发产生的原因

    虽然从宏观上,处理器是并行处理多项任务,但本质上一个处理器在某个时间点只能处理一个任务,属于串行执行。在单处理器的情况下,并发问题源于多道程序设计系统的一个基本特性:进程的相对执行速度不可预测,它取决于其他进程的活动、操作系统处理中断的方式以及操作系统的调度策略。在分布式环境下,并发产生的可能性就更大了,只要大家有依赖的共享资源,就有并发问题的出现,因为互相调用次序更加没法控制。

    并发导致的问题

    全局资源的共享充满了危险。不同任务对同一个共享资源的读写顺序非常关键
    操作系统很难对分配资源进行最优化管理。挂起的线程占有了其他活动线程需要的资源
    

    定位错误非常困难。这种问题来源和触发的不确定性,导致定位问题非常困难
    限制分布式系统横向扩展能力

    具体解决方法

    一次只允许一个进程进入临界区
    一个非临界区停止的进程必须不干涉其他进程
    不允许出现一个需要访问临界区的进程被无限延迟
    一个进程驻留在临界区中的时间必须是有限的
    临界区空闲时,任何需要进入临界区的进程必须能够立即进入

    展开全文
  • JAVA如何解决并发问题

    2020-08-19 01:37:45
    主要介绍了JAVA如何解决并发问题的处理方法,文中讲解的非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
  • Spring 是如何解决并发访问的线程安全性问题的

    Spring 是如何解决并发访问的线程安全性问题的

    参考文章:

    (1)Spring 是如何解决并发访问的线程安全性问题的

    (2)https://www.cnblogs.com/tiancai/p/9627109.html


    备忘一下。


    展开全文
  • Spring 是如何解决并发访问的线程安全性问题 ​springmvc的controller是singleton的(非线程安全的),这也许就是他和struts2的区别吧!和Struts一样,Spring的Controller默认是Singleton的,这意味着每个request...

    Spring 是如何解决并发访问的线程安全性问题

    ​springmvc的controller是singleton的(非线程安全的),和Struts一样,Spring的Controller默认是Singleton的,这意味着每个request过来,系统都会用原有的instance去处理,这样导致了两个结果:一是我们不用每次创建Controller,二是减少了对象创建和垃圾收集的时间;由于只有一个Controller的instance,当多个线程调用它的时候,它里面的instance变量就不是线程安全的了,会发生窜数据的问题。当然大多数情况下,我们根本不需要考虑线程安全的问题,比如dao,service等,除非在bean中声明了实例变量。因此,我们在使用spring mvc 的contrller时,应避免在controller中定义实例变量。

    如果控制器是使用单例形式,且controller中有一个私有的变量a,所有请求到同一个controller时,使用的a变量是共用的,即若是某个请求中修改了这个变量a,则,在别的请求中能够读到这个修改的内容。。

    有几种解决方法:
    1、在Controller中使用ThreadLocal变量
    2、在spring配置文件Controller中声明 scope=“prototype”,每次都创建新的controller
    所在在使用spring开发web 时要注意,默认Controller、Dao、Service都是单例的。

    ThreadLocal 使用范例
    1、ThreadLocalstartTime = newThreadLocal(); 定义一个ThreadLocal 变量
    2、startTime.set(System.currentTimeMillis()); 写入值
    3、startTime.get(); 读取值

    ThreadLocal和线程同步机制相比有什么优势呢?
    ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
    在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。
    而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
    概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

    展开全文
  • 前言 到底什么是线程的不安全?为什么会存在线程的不安全?线程的不安全其实就是多个线程并发的去操作同一共享变量没用做同步所产生意料之外的结果。那是如何体现出来的呢?...那么如何解决的?一般

    前言

    到底什么是线程的不安全?为什么会存在线程的不安全?线程的不安全其实就是多个线程并发的去操作同一共享变量没用做同步所产生意料之外的结果。那是如何体现出来的呢?我们看下面的一个非常经典的例子:两个操作员同时操作同一个银行账户,A操作员存钱,100B操作员取钱50。我们看一下流程。

    两个操作员同时处理,没用做同步这个时候我们发现银行账户最终余额剩余950元,在我们想的最终结果银行账户应该剩余1000+100-50=1050元,在执行过程中我们没有加锁,最终导致了运行结果偏离预期。那么如何解决的?一般的解决措施就是加锁,加同步锁所以这就需要使用者一定要知道锁是什么。我们来看一下加锁之后的效果是不是我们所预期的。

    在添加同步锁后我们可以看到,A操作员和B操作员同时去操作账户,但是A先抢占到资源,所以B就只能等待A操作员释放锁才能去操作银行账户,那么最终结果是我们所预期的吗?答案是的。

    同步的话一般都是加锁,如果现在我想创建多个线程每个线程都是访问的自己的变量呢?各个线程之间毫无关联?

    答案是有的。

    ThreadLocal问题

    ThreadLocal 是JDK提供的,它提供了线程本地变量。什么是线程本地变量呢?其实就是你创建了一个Threadlocal变量,每个访问Threadlocal变量的线程都有一个本地副本。我们看下面的图:

    从上面看出你创建一个ThreadLocal变量,每个访问该的线程都会复制到自己的本地,所以线程操作的都是本地的副本,这也就是说每个线程都是操作的自己本地的变量,那就完美的避免了线程安全的问题。

    在这里还有一个问题。我在写这篇文章的时候看过很多文章,总的来说就是ThreadLocal就是为了解决多线程并发问题而提供的一种方法,还有一种解释就是ThreadLocal的最终目的就是为了解决多线程访问共享资源所产生的。真的对吗?ThreadLocal并没有共享那么从何而来的同步呢?

    自己的想法

    在看了Java并发编程之美后我所理解的Threadlocal提供了线程本地变量的副本,每个线程实际操作的时自己本地的变量副本,也就是说该变量副本只能当前线程访问,就不存在多个线程共享的问题,从Threadlocal名字我们也能看出本地线程。那那那它也就不存在去解决并发问题了。

    如何使用

    我们来看下面的例子。

    输出结果:

    Thread[Thread-1,5,main]====57

    Thread[Thread-0,5,main]====75

    创建了两个线程,它们都在threadlocal上面都set了一个随机数,我们看最后得输出结果每个都是不同得值,那么我们如果把threadlocal替换成一个集合会发生什么,由于两个线程时上个线程生成的随机数57会被第二个线程覆盖掉,而在Threadlocal中两个线程都是操作的自己的本地副本,那么两个线程互不影响都无法操控到对方的数据,因此它们存取的都是不同的值。

    实现原理

    那么Threadlocal是如何实现的呢?在研究Threadlocal的实现原理我们先看一下Thread的内部属性。

    • threadLocals 此线程保存的Threadlocal的值

    inheritableThreadLocals等到后面再说。

    Thread的内部属性中我们看到了这两个默认为null的属性,threadLocals用来保存Threadlocal的本地副本,默认是为null只有调用Threadlocal的set时才会创建。也就是说Threadlocal就类似一个工具,它的作用就是把value的值通过set存在线程每个线程的threadLocals 中,只要线程一直存在threadLocals 也就一直存在。所以当不需要使用本地变量的时候可以调用Threadlocal的remove来清空本地变量。而threadLocals 为什么继承鱼ThreadLocalMap呢?ThreadLocalMap是一个定制的HashMap,而使用Map的原因就是可以每个线程关联多个Threadlocal变量。

    set方法

    我们来看一下set方法是如何实现的。

    可以看出流程非常简单,首先获取当前线程然后在进行下一步操作,我们在看一下getMap做了什么

    getMap主要就是返回了当前threadLocals的属性。那如果map为空呢?

    如果map为空的话就直接创建一个新的ThreadLocalMap。

    我们来看一下流程图。

    get方法

    看一下Get方法

    首先根据当前线程获取实例如果存在就返回,如果不存在就先初始化一个空值,然后判断如果当前threadLoacals不为空就直接set一个空,否则就创建一个变量。

    remove方法

    remove方法相对来说比较简单。

    总结

    Threadlocal的实现原理其实就是通过set把value set到线程的threadlocals属性中,threadlocals类型是Map其中的Key就是Threadlocal的this引用,value就是我们所set的值,如果当前线程不销毁的话threadlocals会一直存在。一直存在的话可能会造成内存溢出,所以使用完之后尽量remove一下。不过在这里又有一个问题那就是如果我的线程想要读取主线程的变量要怎么做?我们上面的例子都是设置的新创建的线程,那么现在我在主线程中set一个值,这个时候我在新创建的线程中可以读取到吗?答案是不可以,因为Threadlocal不支持继承性。

    我们看下面的例子:

    输出结果:

    Thread[Thread-0,5,main]====null

    也就是说Threadlocal不支持继承性,主线程设置了值,在子线程中是获取不到的。那我现在想要获取主线程里面的值要怎么做?

    Threadlocal是实现不了的,不过Threadlocal有一个子类可以实现。InheritableThreadLocalInheritableThreadLocalThreadlocal的实现,我们来看一个简单的例子。

    输出结果:

    Thread[Thread-0,5,main]====1000

    运行结果发现子线程是可以获取到主线程设置的值的,那它是如何实现的?

    我们看一下代码实现:

    InheritableThreadLocal是继承Threadlocal的,并且把threadlocals给替换成inheritableThreadLocals了所以上面的inheritableThreadLocals我要留在最后说,那么替换成inheritableThreadLocals后子线程就可以获取到主线程设置的属性了吗?我们在看一下Thread的实现。

    Thread的初始化方法可以看出,先获取了当前线程(主线程)判断主线程的inheritableThreadLocals不为空的话就调用createInheritedMap方法赋值给子线程中的inheritableThreadLocals。具体这里解释太多。有机会在写一篇文章来解释。

    关于慎用ThreadLocal

    使用ThreadLocal要注意remove !

    ThreadLocal的实现是基于一个所谓的ThreadLocalMap , 在ThreadLocalMap中,它的key是一个弱引用。通常弱引用都会和引用队列配合清理机制使用,但是ThreadLocal是个例外,它并没有这么做。

    这意味着,废弃项目的回收依赖于显式地触发,否则就要等待线程结束,进而回收相应ThreadLocalMap !这 就 是 很 多

    OOM的来源,所以通常都会建议,应用一定要自己负责remove , 并 且 不 要 和 线 程 池 配合,因为worker 线 程 往 往 是 不 会 退 出 的 。

    展开全文
  • 如何解决并发问题

    2019-09-27 09:53:49
    打得到 转载于:https://www.cnblogs.com/yours369000/archive/2010/07/27/1786329.html
  • 前段时间笔者写过一篇关于, 关于《反骨之Java是如何解决并发中的原子性问题》的博文。 其中,提出一个观点:Java中使用互斥锁和CAS解决了并发中的原子性问题。 那么,本篇博文则主要探讨的是: Java中如何利用Java...
  • 上一篇笔记写了如何解决并发导致的三个问题其中两个:缓存导致的可见性问题和编译优化导致的顺序性问题,我们可以通过按需进行禁用缓存和编译优化来解决。指导我们如何按需禁用引出java内存模型的概念。那么这篇笔记...
  • 给每个人返回不一样的微信号信息,这个返回微信号信息的条数是可以变化的,也就是可以1条或者多条,所以limit后接了个变量。...如何实现php并发控制?网上百度的例子多是看不明白。。。求助了!!谢谢
  • 在数据库访问时。如果处理并发访问的问题,或者当一个操作员对一个对象作读操作时。另一个操作员对此对象作写操作的时候,如何避免死锁发生
  • 有三种解决方法 建议使用第三种 1、List list = new Verctor<>(); 1、List list = Collections.synchronizedList(new ArrayList<>()); 1、List list = new CopyOnWriteArrayList<>(); CopyOnWrite...
  • mysql> begin; /*启动事务*/ insert into `like`(user_id, liker_id, relation_ship) values(A, B, 1) on duplicate key update relation_ship=relation_ship | 1; select relation_ship from `like` where user_...
  • 大型网站,比如门户网站,在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。HTML静态化、图片服务器分离、...
  • 在之前的文章中我们讲到过引起多线程bug的三大源头问题(可见性,原子性,有序性问题),java的内存模型(Java Memory Model)可以解决可见性和有序性问题,但是原子性问题如何解决呢? public class Counter { volatile ...
  • 1. 乐观锁和悲观锁两种并发控制方案数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。乐观并发控制(乐观锁)和悲观并发控制...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,932
精华内容 3,172
关键字:

如何解决并发