zoukankan      html  css  js  c++  java
  • 线程的安全隐患

    线程安全的概念是,当多个线程同时访问一个资源时,要确保资源的准确性。也就是说,多个线程必须同步访问一块资源……

    实现线程安全就是加锁。加锁,锁定的代码要尽量少。加锁范围内的代码,同一时间只允许一个线程执行。互斥锁@synchronized (self)的参数,任何继承NSObject的对象都可以,如:self。要保证这个锁对象,所有的线程都能访问到,而且所有线程访问的是同一个锁对象。

    线程实现同步的两种锁:(互斥锁与自旋锁的概念在“区别”中有定义)

      1,互斥锁

      2,自旋锁

    共同点:

      能够锁定一段代码,同一时间,只有一个线程能够执行这段锁定的代码。

    区别:

      互斥锁:在锁定的时候,其他线程会进入睡眠状态,等待条件满足时,重新唤醒。(当A线程在线程池中,CUP进行处理时,其他线程会从线程池出来,进入睡眠状态,等待唤醒)

      自旋锁:在锁定的时候,其他线程会进入一个死循环,也是一直在等待条件满足,一旦条件满足,立即执行,少了一个唤醒过程。(当A线程在线程池中,CPU进行处理时,其他线程还在线程池里面)

    就因为自旋锁少了一个唤醒线程的过程,所以自旋锁的效率要比互斥锁高那么一点点。因此我们在锁定一段代码时,写@synchronized(self){}的时候,在Xcode中并不会有提示,原因是苹果不推荐加锁,加锁性能太差!

    在定义属性时,如:@property(atomic, strong) NSObject *obj; 其关键字atomic为原子性,(默认的属性就为原子属性),原子性就是为多线程设计的,原子性实现单(线程)写多(线程)读。因为写的安全级别要求更高,读的要求低一些,可以多读几次确保数据的正确性。

    在下面重写了setter和getter方法:如果同时重写了setter方法和getter方法,“_成员变量”就不会提供,就可以使用合成指令@synthesize,告诉编译器属性成员变量的名称:

    @synthesize obj = _obj;

    - (void)setObj:(NSObject *)obj

    {

    @synchronized (self){  //模拟锁。真实情况下,使用的不是互斥锁。原子属性内部使用的是自旋锁……

      _obj = obj;

      }

    }

    - (NSObject *)Obj

    {

      return _obj;

    }

    UI线程,我们一般可称为主线程。UIKit中绝大部分类,都不是“线程安全”的。怎么解决这个线程不安全的问题?苹果约定,所有程序更新UI都在主线程中进行,也就不会出现多个线程同时改变一个资源。

    在主线程中更新UI,有什么好处?

      1,在主线程中更新UI,就不会出现多个线程同时改变同一个UI控件。

      2,主线程优先级最高,也就意味着UI的更新优先级高,让用户感觉运行很流畅。

  • 相关阅读:
    LeetCode105 从前序遍历和中序遍历构造二叉树
    LeetCode61 扑克牌中的顺子
    LeetCode141 环形链表
    LeetCode103 二叉树的锯齿形层次遍历
    509 斐波那契数
    剑指29 顺时针打印矩阵
    malloc分配内存2种方式:brk和mmap
    Python学习第139天(Django的分页器(paginator))
    Python学习第138天(Django的用户认真组件)
    Python学习第137天(admin部分参数补充)
  • 原文地址:https://www.cnblogs.com/jone-liu/p/4966613.html
Copyright © 2011-2022 走看看