Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modifying lock to improve code performance #667

Merged
merged 2 commits into from
Mar 27, 2019
Merged

Modifying lock to improve code performance #667

merged 2 commits into from
Mar 27, 2019

Conversation

kinarobin
Copy link
Collaborator

@kinarobin kinarobin commented Mar 22, 2019

  1. 修复MJProperty类中可变容器getter方法没有加锁引发线程安全问题的bug 多线程环境下崩溃 #660 (comment) .

  2. 当前MJExtension使用全局的一把锁,影响效率:
    a-> 针对全局静态容器,为每一个容器新建一把静态全局锁(总共两把静态锁,之前是一把静态锁)。
    b-> 对于MJProperty中可变容器的锁跟随MJProperty类的生命周期一起,不需要使用全局的锁。

  3. 下面方法本来在[self properties]就加锁了,属于单一线程执行,没有必要再加锁:

[MJProperty cachedPropertyWithProperty:]
[MJPropertyType cachedTypeWithCode:]

@kinarobin kinarobin added this to the 3.0.16 milestone Mar 22, 2019
MJProperty *propertyObj = objc_getAssociatedObject(self, property);
if (propertyObj == nil) {
propertyObj = [[self alloc] init];
propertyObj.property = property;
objc_setAssociatedObject(self, property, propertyObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
MJExtensionSemaphoreSignal
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MJPropertySemaphoreCreate
MJ_LOCK(_propertySemaphore);
NSArray *cachedProperties = [self properties];
MJ_UNLOCK(_propertySemaphore);

[self properties];方法已加锁,此处并没有其他线程同时进入,所以并不需要加锁

MJPropertyType *type = types[code];
if (type == nil) {
type = [[self alloc] init];
type.code = code;
types[code] = type;
}
MJExtensionSemaphoreSignal
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

Copy link
Collaborator

@wolfcon wolfcon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上面有一些代码冗余的问题

MJExtensionSemaphoreCreate
MJExtensionSemaphoreWait
MJClassSemaphoreCreate
MJ_LOCK(_classSemaphore);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MJClassSemaphoreCreate 这里的宏, 并没有指出真正的变量内容
MJ_LOCK(_classSemaphore); 这里使用的 _classSemaphore 太隐含了.

dispatch_semaphore_wait(signalSemaphore, DISPATCH_TIME_FOREVER);

#define MJExtensionSemaphoreSignal \
dispatch_semaphore_signal(signalSemaphore);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

上面删掉的代码在其他类里的改动和放在这里应该是一样的. define 宏定义只是在编译阶段替换而已.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用 MJ_LOCK () 主要原因是不使用全局的一把锁,在每个对应的功能点加锁,后期如果还有线程安全相关问题,使用自己定义的锁,提高锁的效率:

MJ_LOCK(self.propertyKeysLock);
self.propertyKeysDict[key] = propertyKeys;
MJ_UNLOCK(self.propertyKeysLock);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

主要目的是不使用全局的那一把锁

@kinarobin kinarobin merged commit c0aee25 into CoderMJLee:master Mar 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants