需要实现一个消息队列,队列具有 FIFO 特点,即先入先出,在这里采用单向链表实现队列逻辑。
本次要实现的队列要求:
1. 节点可以存放任意类型数据
2. 线程安全
简单说明一下:
1. 创建CFNode类,用作节点,其data属性和next属性都是 atomic,即只能单线程访问属性。
2. 创建CFList类,用以push节点和pop节点
3. 删除操作为不必要操作,在这里实现了纯属个人技痒,同理可实现节点更新、插入等操作,在这里不做过多介绍。
CFList.h文件
1 // 2 // CFList.h 3 // ListTest 4 // 5 // Created by MiaoCF on 2018/2/26. 6 // Copyright © 2018年 MiaoCF. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 typedef BOOL(^CFComparator)(id obj1, id obj2); 12 13 @interface CFNode : NSObject 14 15 @property (atomic, strong) id data; 16 @property (atomic, strong) CFNode *next; 17 @end 18 19 @interface CFList : NSObject 20 21 @property (atomic, strong, readonly) CFNode *head; 22 @property (atomic, strong, readonly) CFNode *tail; 23 @property (atomic, assign, readonly) NSInteger size; 24 25 // 1 creat 26 - (instancetype)initList; 27 28 // 2 appendNode 29 - (void)appendData:(id)data; 30 31 // 3 popNode 32 - (id)popNode; 33 34 // 4 deleteNode 35 - (BOOL)deletNode:(CFNode *)node with:(CFComparator)comparator;// func equal to find node 36 @end
CFList.m文件
注意:
1. 使用了线程阻塞的互斥锁
2. 删除节点时,用户自己实现 CFComparator 进行比较。
3. 节点重复问题: 有多个节点数据相同 全部删除
1 // 2 // CFList.m 3 // ListTest 4 // 5 // Created by MiaoCF on 2018/2/26. 6 // Copyright © 2018年 MiaoCF. All rights reserved. 7 // 8 9 #import "CFList.h" 10 11 @implementation CFNode 12 @end 13 14 @interface CFList() 15 @property (atomic, strong) NSLock *mutex; 16 @end 17 18 @implementation CFList 19 20 - (instancetype)initList { 21 22 self = [super init]; 23 24 _mutex = [[NSLock alloc] init]; 25 26 self.head = nil; 27 self.tail = nil; 28 29 return self; 30 } 31 32 33 // idea: 记录 head 和 tail 节点, head只管删除节点, tail只管添加节点 34 35 - (void)appendData:(id)data { 36 [_mutex lock]; 37 38 CFNode *node = [[CFNode alloc] init]; 39 node.data = data; 40 node.next = nil; 41 42 if (_head == nil) { 43 _head = node; 44 } else { 45 _tail.next = node; 46 } 47 _tail = node; 48 _size ++; 49 50 [_mutex unlock]; 51 } 52 53 - (id)popNode { 54 [_mutex lock]; 55 56 id res = nil; 57 58 if (_head != nil) { 59 res = _head.data; 60 61 CFNode *temp = _head; 62 _head = temp.next; 63 if (_head == nil) { 64 _tail = nil; 65 } 66 67 temp.next = nil; 68 _size --; 69 } 70 71 [_mutex unlock]; 72 return res; 73 } 74 75 // 节点重复问题: 有多个节点数据相同 如何处理? 76 77 - (BOOL)deletNode:(CFNode *)node with:(CFComparator)comparator{ 78 79 [_mutex lock]; 80 81 //空链表 82 if (_head == nil) { 83 [_mutex unlock]; 84 return NO; 85 } 86 87 CFNode *currentNode = _head; 88 CFNode *previousNode = currentNode; 89 90 //从第二个节点开始判断 91 while (currentNode) { 92 93 if (comparator(currentNode, node)) { //移除节点 94 95 previousNode.next = currentNode.next; 96 currentNode.next = nil; 97 98 // 节点重复问题: 有多个节点数据相同 全部删除 99 if (previousNode.next == nil) { // 一直遍历到末尾,可以清除重复节点 100 101 [_mutex unlock]; 102 return YES; 103 } 104 } 105 previousNode = currentNode; 106 currentNode = currentNode.next; 107 108 } 109 110 [_mutex unlock]; 111 return NO; 112 }
113 @end