共享资源加锁的操作方法-10-多线程

  1 在多线程的编程环境中,锁的使用必不可少!
  2 于是,今天来总结一下为共享资源加锁的操作方法。
  3
  4 一、使用synchronized方式
  5
  6     //线程1
  7     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  8         @synchronized(_myLockObj){
  9             [obj1 method1];
 10             sleep(30);
 11         }
 12         @synchronized(obj1){
 13
 14
 15
 16         }
 17     });
 18
 19     //线程2
 20     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 21         sleep(1);
 22         @synchronized(_myLockObj){
 23             [obj1 method2];
 24         }
 25     });
 26
 27 }
 28
 29 这样,就会起到锁的作用,线程2会等待线程1执行完成@synchronized(obj){}块后,在执行。从而起到锁的作用。
 30
 31 2.使用NSLock方式
 32
 33 先贴一个例子:
 34
 35 1. TestObj.h
 36
 37 @interface TestObj : NSObject
 38 - (void)method1;
 39 - (void)method2;
 40 @end
 41
 42 2. TestObj.m
 43
 44 #import "TestObj.h"
 45
 46 @implementation TestObj
 47
 48 - (void)method1{
 49     NSLog(@"%@",NSStringFromSelector(_cmd));
 50     NSLog(@"Current thread = %@", [NSThread currentThread]);
 51     NSLog(@"Main thread = %@", [NSThread mainThread]);
 52 }
 53
 54 - (void)method2{
 55     NSLog(@"%@",NSStringFromSelector(_cmd));
 56     NSLog(@"Current thread = %@", [NSThread currentThread]);
 57     NSLog(@"Main thread = %@", [NSThread mainThread]);
 58
 59 }
 60
 61 @end
 62
 63 3.在需要锁的视图控制器中,申明锁对象。
 64
 65  TestObj *obj = [[TestObj alloc] init];
 66     NSLock *lock = [[NSLock alloc] init];
 67
 68 4.多线程状态下,锁操作
 69
 70
 71 //线程1
 72     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 73         [lock lock];
 74         [obj method1];
 75         sleep(30);
 76         [lock unlock];
 77     });
 78
 79     //线程2
 80     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
 81         sleep(5);//以保证让线程2的代码后执行
 82         [lock lock];
 83         [obj method2];
 84         [lock unlock];
 85     });
 86
 87 5.总结
 88
 89 使用时,基本方法就是:
 90 [lock lock];
 91 [obj yourMethod];
 92 [lock unlock];
 93
 94 我们称[obj yourMethod]为“关键部分”。
 95 NSLock的执行原理:
 96 某个线程A调用lock方法。这样,NSLock将被上锁。可以执行“关键部分”,完成后,调用unlock方法。
 97 如果,在线程A 调用unlock方法之前,另一个线程B调用了同一锁对象的lock方法。那么,线程B只有等待。直到线程A调用了unlock。
 98
 99 最后,还是看看API中对NSLock的一些说明
100
101
102 @protocol NSLocking
103
104
105 lock 方法
106 - (void)lock
107 获得锁
108
109 unlock 方法
110 - (void)unlock
111 释放锁
112
113 @interface NSLock
114
115 lockBeforeDate: 方法
116 - (BOOL)lockBeforeDate:(NSDate *)limit
117 在指定的时间以前得到锁。YES:在指定时间之前获得了锁;NO:在指定时间之前没有获得锁。
118 该线程将被阻塞,直到获得了锁,或者指定时间过期。
119
120
121 tryLock 方法
122 - (BOOL)tryLock
123 视图得到一个锁。YES:成功得到锁;NO:没有得到锁。
124
125
126 setName: 方法
127 - (void)setName:(NSString *)newName
128 为锁指定一个Name
129
130 name 方法
131 - (NSString *)name
132 返回锁指定的Name
133
134
135 三、使用GCD中dispatch_semaphore_t和dispatch_semaphore_wait
136
137 TestObj *obj = [[TestObj alloc] init];
138     dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
139
140     //线程1
141     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
142         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
143         [obj method1];
144         sleep(10);
145         dispatch_semaphore_signal(semaphore);
146     });
147
148     //线程2
149     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
150         sleep(1);
151         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
152         [obj method2];
153         dispatch_semaphore_signal(semaphore);
154     });
155
156 关于GCD中dispatch_semaphore_create和dispatch_semaphore_wait的使用。请参见我的另一篇博客:
157
158 GCD(Grand Central Dispatch)和Block 使用-浅析
时间: 2024-08-08 08:55:28

共享资源加锁的操作方法-10-多线程的相关文章

关于java多线程任务执行时共享资源加锁的方式思考

1.加锁方式: 1-1.使用synchronized关键字进行方法或代码块的加锁方式 1-2.使用ReentrantLock类提供的lock()方法的方式 2.代码实现(传统的银行取款存款问题): 2-1.Account.java类:账户类 package com.java.thread; import java.util.concurrent.locks.ReentrantLock; /** * 账户类 * @author steven * */ public class Account {

Java多线程、主线程等待所有子线程执行完毕、共享资源

1.Java创建与启动线程 Java提供两种方式创建和启动线程:1.直接Thread类,2.实现Runable接口. 1.1  继承Thread类 public class myThread extends Thread { public void run(){ for(int i=0;i<5;i++){ System.out.println(this.getName()+":"+i); } } public static void main(String[] args){ //

多重影分身——C#中多线程的使用二(争抢共享资源)

只要服务器承受得了,我们可以开任意个线程同时工作以提高效率,然而 两个线程争抢资源可能导致数据混乱. 例如: public class MyFood { public static int Last { get; set; } public MyFood() { Last = 500; } public void EatFood() { int foods = Last; Thread.Sleep(1000); Last = foods - 1; Console.WriteLine(Last);

JAVA学习笔记 -- 多线程之共享资源

在多线程程序运行过程中,可能会涉及到两个或者多个线程试图同时访问同一个资源.为了防止这种情况的发生,必须在线程使用共享资源时给资源"上锁",以阻挡其它线程的访问.而这种机制也常常被称为互斥量,本文主要介绍它的两种方式synchronized和Lock . 1.synchronized 当任务要执行被synchronized关键字保护的代码片段的时候,它会检查锁是否可用,然后获取锁,执行代码,释放锁.synchronized也有两种用法: A.synchronized方法 import

【JAVA并发】共享资源访问

什么是共享资源 先了解下JAVA程序在运行时内存的分布,由以下部分组成 堆:所有线程共享一个堆:存放的都是new 出来的对象: 方法区:所有线程共享一个方法区:里面存放的内容有点杂,可以认为是除堆和栈中的其它东西(如类信息,静态变量,常量,代码等): 程序计数器:也叫PC,存放下一条指令所在单元的地址的地方; JAVA栈:每个线程都有一个自己的JAVA栈;存放的一般是方法的局部变量,方法出口信息等: 本地方法栈:与JAVA栈类似,区别是使用的对象不一样,本地方法栈是给Native方法使用的,JA

Java使用wait() notify()方法操作共享资源详解_java - JAVA

文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 Java多个线程共享资源: 1)wait().notify()和notifyAll()方法是本地方法,并且为final方法,无法被重写. 2)调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(即锁,或者叫管程) 3)调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程,如果有多个线程都在等待这个对象的monitor,则只能唤醒其中一个线程: 4

【java项目实战】ThreadLocal封装Connection,实现同一线程共享资源

线程安全一直是程序员们关注的焦点.多线程也一直是比較让人头疼的话题,想必大家以前也遇到过各种各种的问题.我就不再累述了.当然,解决方案也有非常多,这篇博文给大家提供一种非常好的解决线程安全问题的思路. 首先.我们先简单的认识一下ThreadLocal,之后是实例+解析,最后一句话总结. 1.认识一下ThreaLocal 认识ThreadLocal必需要通过api文档,不只具有说服力,并且它会给你更加全面的解释.以下我我给大家从api文档上截取一张图,并标出来了七点需要重点理解的内容,实例过后的解

JAVA 10(多线程)

创建线程: 通过对java.lang包的查找,继承Thread类可以创建线程 1,建立类继承Thread类 2,复写Thread中的ran方法. 3,调用线程的start()方法,该方法的作用是,启动线程,调用ran方法. public class Test { public static void main(String args[]) { Demo a= new Demo(); a.start(); for(int x=0;x<=100;x++) System.out.println("

wpf多程序集之间共享资源字典--CLR名称空间未定义云云

wpf多程序集之间共享资源字典--CLR名称空间未定义云云 分类: WPF 2012-10-28 10:57 1162人阅读 评论(0) 收藏 举报 以下介绍如何创建可用于在多个程序集之间共享的资源字典 1.新建Wpf自定义控件库,名称为MyContorlLib,项目资源结构图如下: 2.打开Themes文件夹中的Generic.xaml文件,在根元素中添加如下名称空间:xmlns:local="clr-namespace:MyContorlLib"因为待会儿要用到该名称空间下的一个类