发表时间:2022-03-25来源:网络
好记性是真的不如烂笔头,只记得一些知识碎片对我并不会有所帮助
charpter1.简介
1.线程与进程的区别
进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义。线程可以利用进程所拥有的资源,在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统多个程序间并发执行的程度。
我的理解中,一个程序跑起来就是运行了一个进程,进程也就是这个程序的执行过程。而线程则是这个程序为了提高运行效率,将自己的进程所拥有的资源分成几个独立运行的程序片段同时运行,以此提高资源使用效率进而提高系统的效率。
2.线程的优缺点
参加此文:
我的理解上,线程轻量、可以高效率利用cpu,可以避免单线程程序在等待响应/计算结束期间什么都不做的缺点。但是代码编写和调试困难,如果线程操作数据时没有原子性则容易导致数据错误,如果线程滥用锁则容易导致死锁,同时切换线程也需要系统开销,可能反过来降低运行效率
3.就算我们什么都不做,我们开发时,框架依旧替我们创建了线程。
作为web开发,最典型的就是servlet容器了
charpter2.线程安全--原子性
1.线程安全的本质是对(共享、可变)状态的管理,一个对象的状态也就是是它所拥有的数据,共享意味着这些数据可以被多个进程访问,可变则意味着这些数据可以被改变,无论何时,只要有多于一个进程可以访问给定的状态变量,并且其中一个进程可以改变状态变量,则必须使用同步机制协调这些线程对该变量的访问。
2.无(共享、可变)状态对象永远是线程安全的
3.为了保证线程安全,对状态进行检查再修改(getCount ,count++,insertCount)的操作必须是原子性的.最简单的做法是使用java内置的原子性机制--锁。
4.synchronized锁是互斥锁(同一时间只有一个线程可以拥有)也是可重入锁(线程每次获取锁时计数器+1,每次退出同步块时计数器-1,为0时释放锁)
5.一个对象中,每个需要保护的状态变量需要由同一个锁保护。
6.因为锁的消耗非常高昂,所以我们需要仔细设计,将不影响同步并且耗时的操作尽可能的剥离到同步块外以保障性能。
charpter3.共享对象
1。正如我们所知,线程安全的基础是原子性、可见性、有序性。原子性的关键在于操作状态的操作在执行线程之外的线程来看应该是不可分割的。可见性的问题则在于写线程操作了状态之后,读线程应该能够立刻获取最新的状态----如果没有使用同步机制,就不能保证这一点。
2.能实现可见性的同步机制不只有锁,还有volatile关键字,其机理参见
啊,会画画的人真是厉害,总而言之,结论上:
1.)volatile修饰的变量可以保证一个线程对该变量的写happens-before 一个线程对该变量的读,其机理是内存屏障
2.)Volatile可以用来修饰long和double类型的变量使其以原子方式执行(jvm运行将64位基本类型的读和写分成两个32位的读写哦,所以在多线程情况下这两个类型并不是天然原则性的)
3.)Volatile关键字主要用于保证内存可见性和有序性
3.发布和逸出
发布(publish)对象意味着其作用域之外的代码可以访问操作此对象。例如将对象的引用保存到其他代码可以访问的地方,或者在非私有的方法中返回对象的引用,或者将对象的引用传递给其他类的方法。为了保证对象的线程安全性,很多时候我们要避免发布对象,但是有时候我们又需要使用同步来安全的发布某些对象。
逸出即为发布了本不该发布的对象。
常见的发布方式是把对象放到静态域(例:static Map)中,或者发布内部类实例(因为内部类对象拥有外部类对象的引用)
为了避免逸出,要谨慎的注意在对象不应发布的时候就别发布,这里举了一个this逸出的例子,也就是在构造方法中启动线程,导致未构造完成的对象被发布。
4.线程封闭
如上一章所述,为了多线程的安全,只有(共享、可变)状态需要同步机制的管理,那么我们让状态不共享,那自然就不需要关心它的同步了。这就是线程封闭。
最简单的做法就是使用方法内部的局部变量(天然线程安全)。更加规范的方法是使用ThreadLocal,这个类可以帮助我们将对象与线程绑定,为每个线程维护一个对象的拷贝,这样即能让多个线程使用同一个对象,又因为每个线程使用的都是单独的副本所以不需要考虑同步的问题。ThreadLocal的详细介绍可以参见:
总而言之,ThreadLocal的使用可以帮助我们维护线程安全,也可以用来获取线程的上下文。而ThreadLocal的具体事项使得ThreadLocal有内存溢出的危险,为了规避此危险,我们应:
5.不可变性
状态不共享的做法如上,我们还可以让状态不可变来保证线程安全。
最简单的做法当然是使用final关键字咯。注意被修饰的对象其成员也要是final才算是不可变。
(todo)这里提供了通过volatile实现不可变的实例,感觉对初学者太难了,不如一起用final。
6.安全发布
todo,在我有更深理解之前,先上这三张图吧
图一、怎样安全发布对象
图二、不可变、技术上可变但是不会改变、可变对象的安全发布方法
图三、共享对象的最优实践
皓盘云建最新版下载v9.0 安卓版
53.38MB |商务办公
ris云客移动销售系统最新版下载v1.1.25 安卓手机版
42.71M |商务办公
粤语翻译帮app下载v1.1.1 安卓版
60.01MB |生活服务
人生笔记app官方版下载v1.19.4 安卓版
125.88MB |系统工具
萝卜笔记app下载v1.1.6 安卓版
46.29MB |生活服务
贯联商户端app下载v6.1.8 安卓版
12.54MB |商务办公
jotmo笔记app下载v2.30.0 安卓版
50.06MB |系统工具
鑫钜出行共享汽车app下载v1.5.2
44.7M |生活服务
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-03-26
2022-02-15
2022-02-14