03-互斥锁和自旋锁

互斥锁和自旋锁


互斥锁(Synchronized:)

  • @synchornized(锁){}
    • 任意对象就是锁(常用self)
  • 下一线程会进入sleep状态,会自动从调度池中移除
  • 下一线程在上一线程解锁的时候再放到调度池中
  • 只要被synchronized扩住的代码, 就是被锁住的代码.也就是说, 只要被synchronized{}扩住, 就能实现同一时刻, 只能有一个线程操作
	@synchornized(self)
	{
		//需要加锁的部分
	}

自旋锁(Atomic:)

  • 下一线程会一直在调度池中等待(不会睡眠)
@property(nonatomic,assign)int a;

案例(售票员买票)

技巧

  • 1.@synchronized单词的快速记忆方法
    [NSUserDefaults standardUserDefaults] synchronize + d
  • 2.开发中如果需要加锁, 一般都使用self

注意

    1. 如果多条线程访问同一个资源, 那么必须使用同一把锁才能锁住
    1. 在开发中, 尽量不要加锁, 如果必须要加锁, 一定记住, 锁的范围不能太大, 哪里会有安全隐患就加在哪里

需求:三个售票员卖100张票

@interface ViewController ()
@property (nonatomic, strong) NSThread *thread1; /**< 售票员1 */
@property (nonatomic, strong) NSThread *thread2; /**< 售票员2 */
@property (nonatomic, strong) NSThread *thread3; /**< 售票员2 */

@property (nonatomic, assign)NSUInteger totalCount; /**< 票的总数 */

@property (nonatomic, strong) NSObject *lockObj; /**< 锁 */

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 0.初始化票数
    self.totalCount = 100;
    // 1.创建3个售票员
    NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    thread1.name = @"售票员1";
    self.thread1 = thread1;
    NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    thread2.name = @"售票员2";
    self.thread2 = thread2;
    NSThread *thread3 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    thread3.name = @"售票员3";
    self.thread3 = thread3;
    
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 2.让3个售票员同事售票
    [self.thread1 start];
    [self.thread2 start];
    [self.thread3 start];
}

// 售票方法
- (void)saleTicket
{
    while (1) {
        //增加用户体验
        NSLog(@"欢迎光临");
        
//       NSObject lockObj = [[NSObject alloc] init];
       
       //开发中锁对象可以用self
        @synchronized(self){ // 锁住
        
            // 1.查询剩余的票数
            NSUInteger count = self.totalCount;
            // 2.判断是否还有余票
            if (count > 0) {
                // 线程1 100
                [NSThread sleepForTimeInterval:0.1];
                // 2.1卖票
                self.totalCount = count - 1; // 99
                NSLog(@"%@卖了一张票, 还剩%zd票", [NSThread currentThread].name, self.totalCount);
            }else
            {
                // 3.提示客户, 没有票了
                NSLog(@"对不起, 没有票了");
                break;
            }
        } // 解锁
    }
}

//必须是同一个锁
- (NSObject *)lockObj
{
    if (!_lockObj) {
        _lockObj = [[NSObject alloc] init];
    }
    return _lockObj;
}
原文地址:https://www.cnblogs.com/KrystalNa/p/4780313.html