方案:synchronized,volatile+CAS(compareAndSet),atomic包,Lock接口

java同步和IO同步的对比:

都是同步异步的方案问题,一个操作的是java代码(实际是堆和方法区),一个操作的是TCP RecvBuffer而已

线程安全方案:

https://www.cnblogs.com/jianmianruxin/p/7583262.html
---------------------
原文:https://blog.csdn.net/u010287873/article/details/82387494

http://blog.csdn.net/yangcheng33/article/details/47708631

线程安全实现方案 

线程不安全的原因是:多个线程使用线程共享数据时不能保证更新操作的原子性。

线程安全策略:

一:互斥同步

这是一种悲观同步方案,互斥同步要求使用共享资源的线程必须满足对共享数据的访问具备原子性。如果该线程没有完全结束对共享数据的访问,其他线程不得访问共享数据。

互斥同步的实现方式有synchronized和ReentrantLock两种方式:

前者获取锁的过程中获取不到时线程会被放入队列陷入阻塞等待。后者可以提供非阻塞获取锁的方式,比如trylock和interruptibly。

       synchronized既可以修饰实例方法也可以修饰类方法,也可以作为同步块。

1.某个线程获取到对象锁时,这个对象的所有被synchronized修饰的同步方法将被此线程锁住,其他线程只能访问此对象的非synchronized方法。

2.每个对象都有锁,一个对象被一个线程上锁,不影响同属一个类的其他实例对象的锁状态,其他线程可以访问另一个实例对象的非同步方法。

3.synchronized修饰类方法时:同步类方法被执行时所有对象的锁状态变为1,所有对象被上锁。

        ReentrantLock跟synchronized相比还包括了中断锁等候和定时锁等候,当线程A先获得了对象锁,线程B在指定时间内无法获取锁时可以自动放弃等待该锁。

ReentrantLock使用代码实现,系统无法自动释放锁,需要在代码中finally子句中显式释放锁lock.unlock();
Lock lock  = new ReentrantLock();
lock.lock();
try{ //可能会出现线程安全的操作 }finally{ //一定在finally中释放锁 //也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常 lock.ublock(); }
ReentranLock的API:

  • void lock() 获取锁,调用该方法当前线程将会获取锁,当锁获取后,该方法将返回。获取不到会一直获取,因此此方法是阻塞的。
  • boolean tryLock() 尝试非阻塞的获取锁,调用该方法立即返回,true表示获取到锁
  • boolean tryLock(long time,TimeUnit unit) throws InterruptedException 和tryLock()方法是类似的,只不过区别在于这个方法在拿不到锁时会等待一定的时间,在时间期限之内如果还拿不到锁,就返回false
  • void lockInterruptibly() throws InterruptedException 可中断获取锁,与lock()方法不同之处在于该方法会响应中断,即在锁的获取过程中可以中断当前线程
  • 当一个线程获取了锁之后,是不会被interrupt()方法中断的。interrupt()方法不能中断正在运行过程中的线程,线程处于阻塞状态才可被中断(如线程调用了sleep,join,wait方法等),但线程获取锁的过程中不可被中断(除了上面新学的方法lockInterruptibly)。线程中断只能。
  • Thread.interrupt()方法不会中断一个正在运行的线程。它的作用是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。

    interrupt方法并不是强制终止线程,它只能设置线程的interrupted状态,被block的线程(sleep() or join())在被调用interrupt时会产生InterruptException(lock是不会的,直到获取到锁才会去处理中断标志),此时是否终止线程由本线程自己决定

  • 说白了线程的中断方法的作用并不是中断线程,而是把已经阻塞的线程的中断标志改为true(起作用的基本条件是阻塞),但这个标志不一定立即起作用,lockInterruptibly会立即处理该标志,但lock()方法直到获取到了锁才会处理中断标志。
  • void unlock() 释放锁

ReentrantLock是Lock接口一种常见的实现,它是支持重进入的锁即表示该锁能够支持一个线程对资源的重复加锁。该锁还支持获取锁时的公平与非公平的选择。 
关于锁的重进入,其实synchronized关键字也支持。如前所述,synchronized关键字也是隐式的支持重进入而对于ReentrantLock而言,对于已经获取到锁的线程,再次调用lock()方法时依然可以获取锁而不被阻塞。

synchronized和ReentrantLock都是可重入锁,可重入性在我看来实际上表明了锁的分配机制:基于线程的分配,而不是基于方法调用的分配。举个简单的例子,当一个线程执行到某个synchronized方法时,比如说method1,而在method1中会调用另外一个synchronized方法method2,此时线程不必重新去申请锁,而是可以直接执行方法method2。

  看下面这段代码就明白了:

1
2
3
4
5
6
7
8
9
class MyClass {
    public synchronized void method1() {
        method2();
    }
     
    public synchronized void method2() {
         
    }
}

  上述代码中的两个方法method1和method2都用synchronized修饰了,假如某一时刻,线程A执行到了method1,此时线程A获取了这个对象的锁,而由于method2也是synchronized方法,假如synchronized不具备可重入性,此时线程A需要重新申请锁。但是这就会造成一个问题,因为线程A已经持有了该对象的锁,而又在申请获取该对象的锁,这样就会线程A一直等待永远不会获取到的锁。

  而由于synchronized和Lock都具备可重入性,所以不会发生上述现象。

刚刚提到的公平获取锁与非公平获取锁。如果在绝对时间上,先对于锁进行获取的请求一定先被满足,那么这个锁就是公平的,反之就是非公平的。公平的获取锁也就是等待时间最久的线程优先获取到锁。ReentrantLock的构造函数来控制是否为公平锁。

我在第一次了解到公平获取锁与非公平获取锁的时候,第一反应是公平获取锁的效率高,应该使用公平获取锁。但实际的情况是,非公平获取锁的效率远远大于公平获取锁。

java的线程是映射到操作系统的原生线程之上的,如果要阻塞或唤醒一个线程都需要操作系统来帮忙完成,因此需要从用户态切换到内核态。对于代码简单的同步块,状态转换消耗的时间可能比代码执行的时间还要长。因此重量级的synchronized除非有必要否则不使用。API中ReentrantLock和synchronized一样是互斥的方案,一样是可重入的,但多了一些高级功能如可中断,公平锁及锁可以绑定条件等。

二:非阻塞同步

三:可重入代码

如果一段代码的执行结果是可预测的,并且输入相同的数据会得到相同的数据,那么这段代码就是可重入代码,当然也是线程安全的。

                                                             用户态与内核态的切换

内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序

用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取

为什么要有用户态和内核态

由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络, CPU划分出两个权限等级 -- 用户态 和 内核态

所有用户程序都是运行在用户态的, 但是有时候程序确实需要做一些内核态的事情, 例如从硬盘读取数据, 或者从键盘获取输入等. 而唯一可以做这些事情的就是操作系统, 所以此时程序就需要先操作系统请求以程序的名义来执行这些操作.

这时需要一个这样的机制: 用户态程序切换到内核态, 但是不能控制在内核态中执行的指令

这种机制叫系统调用, 在CPU中的实现称之为陷阱指令(Trap Instruction)

他们的工作流程如下:

  1. 用户态程序将一些数据值放在寄存器中, 或者使用参数创建一个堆栈(stack frame), 以此表明需要操作系统提供的服务.
  2. 用户态程序执行陷阱指令
  3. CPU切换到内核态, 并跳到位于内存指定位置的指令, 这些指令是操作系统的一部分, 他们具有内存保护, 不可被用户态程序访问
  4. 这些指令称之为陷阱(trap)或者系统调用处理器(system call handler). 他们会读取程序放入内存的数据参数, 并执行程序请求的服务
  5. 系统调用完成后, 操作系统会重置CPU为用户态并返回系统调用的结果
新生的小心情

转载于:https://www.cnblogs.com/PrestonL/p/9938705.html

[网络开发]同步与线程安全方案相关推荐

  1. iOS开发——高级篇——线程同步、线程依赖、线程组

    前言 对于iOS开发中的网络请求模块,AFNet的使用应该是最熟悉不过了,但你是否把握了网络请求正确的完成时机?本篇文章涉及线程同步.线程依赖.线程组等专用名词的含义,若对上述名词认识模糊,可先进行查 ...

  2. 1588PTP时钟同步(网络时钟服务器)技术应用方案

    1588PTP时钟同步(网络时钟服务器)技术应用方案 1588PTP时钟同步(网络时钟服务器)技术应用方案 京准电子科技(VX-ahjzsz)原创文章,请勿转载. 概述 1.1. PTP起源 伴随着网 ...

  3. 如何实现一个简单的网络帧同步方案

    在网络游戏中,网络同步方案大概有下面三种: 状态同步,即state synchronization 快照同步,即 snapshot synchronization 帧同步,即lock step syn ...

  4. iOS开发系列--网络开发(转)

    iOS开发系列--网络开发 2014-10-22 08:34 by KenshinCui, 66365 阅读, 56 评论, 收藏, 编辑 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微 ...

  5. python网络编程视频教程_Java网络开发视频教程 – 一站式学习Java网络编程视频教程 全面理解BIO(无密)...

    Java网络开发视频教程 – 一站式学习Java网络编程视频教程 全面理解BIO(无密) 全面理解BIO/NIO/AIO 网络层编程,是每一个开发者都要面对的技术.课程为解决大家学习网络层知识的难题, ...

  6. .NET 6 Preview 6 正式发布: 关注网络开发

    微软.NET 团队的项目经理在博客上发布了.NET 6 Preview 6,  在候选发布阶段之前的倒数第二个预览版,也就是8月份还会发布一个Preview 7,9月份开始进入RC,两个候选版本将专注 ...

  7. 三、Android网络开发

    传送门 <一.Android Studio的安装和使用> <二.Android界面开发> <三.Android网络开发> <四.狗狗大全应用实战> 视频 ...

  8. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

  9. 网络主机防泄密安全保护方案

    网络主机防泄密安全保护方案 2008-3-22 请预先参考<可信移动存储管理白皮书> --- 附录 一.主机移动存储介质安全管理 移动存储介质管理系统分别从主机层次和传递介质层次对文件的读 ...

最新文章

  1. numpy中的broadcasting
  2. Oracle RAC集群体系结构
  3. matlab运行就是编译么,matlab编译运行c文件
  4. 巴黎市中心降下2019年第一场雪
  5. LeetCode 1679. K 和数对的最大数目(哈希)
  6. powershell目录带空格_powershell - 如何在命令行的路径中运行带有空格的powershell脚本? - SO中文参考 - www.soinside.com...
  7. python codefirst_Python code.co_consts方法代码示例
  8. 京东或将裁员 12000 人!雷军年薪百亿;马云:阿里没人敢跟我打赌 | 极客头条
  9. 前人栽树,后人擦屁股
  10. 添加Centos缺失的命令
  11. mktime()的格式
  12. |洛谷|动态规划|P2014 选课
  13. WPF教程二:布局之StackPanel面板
  14. CSS-线性渐变无畸变-环形普通进度条-环形能量块进度条-局部环形普通进度条
  15. 32年魔咒破解,见证国足3:0大胜韩国
  16. Java实现 LeetCode 824 山羊拉丁文(暴力)
  17. 文件夹访问被拒绝 你需要权限来执行此操作,你需要来自SYSTEM的权限才能对此文件夹进行更改
  18. python表情包多样化聊天室_Python | 信不信我分分钟批量做你大堆的表情包?
  19. 老熊一亩三分地里的Oracle工具
  20. 头条2019.3.16笔试题

热门文章

  1. Proteus常见电平状态
  2. Linux 系统应用编程——线程基础
  3. Linux 系统应用编程——网络编程(高级篇)
  4. Linux C 学习 单向链表
  5. Controller向View传值方式总结
  6. React开发(259):react项目理解 ant design debug
  7. [react] 浏览器为什么无法直接JSX?怎么解决呢?
  8. [react] 如何更新组件的状态?
  9. Taro+react开发(92):taro中的事件处理
  10. Taro+react开发(46)taro中环境判断