单链表<br>java单链表的实现, 多线程 ,读写锁

来源:互联网 发布:mac版阿里旺旺10.9.5 编辑:程序博客网 时间:2024/05/16 12:40

1, 读写锁

(1)读锁与读锁不互斥, 即一个拥有lock锁的读锁的线程在读a变量时, 另一个同样拥有lock锁的读锁的线程可以同时读a变量

(2)读锁与写锁互斥, 即一个拥有lock锁的读锁的线程在读a变量时,另一个同样拥有lock锁的写锁的线程不可以同时修改a变量, 反之亦然

(3)写锁与写锁互斥, 即一个拥有lock锁的读锁的线程在读a变量时,其他拥有lock锁(无论读锁或写锁)的线程都不能读或者写a变量

2, 此链表没有主动的调用垃圾回收机制, 如果此链表的节点数量很多很多, 同时又频繁的增加,删除节点, 会大量内存浪费

package util;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;/** * 单向链表<br> * 许多超出索引范围的异常我没有处理, 会抛出空指针异常.<br> * 加上了线程锁, 保证操作的同步性(同步性在下没有自测,不保证没bug).<br> * 没有添加删除尾节点的方法,因为是单向列表,只能从上一个节点找到下一个节点,要实现也可以,只是我懒 * @author xiezc * @date 2016-3-31 下午1:12:27 *  */public class LinkList<T> {/** * 定义一个头节点 */private Node first; // 定义一个头结点/** * 定义尾节点 */private Node finalNode;// 定义尾节点/** * 读写锁 */private ReadWriteLock rwl = new ReentrantReadWriteLock(); // 读写锁:上面有一个读锁和一个写锁/** * 插入一个头节点 *  * @param data * @author xiezc * @throws Exception */public boolean addFirstNode(T data) {Node node = new Node(data);rwl.writeLock().lock();try {if (first == null) {first = node;finalNode = node;node.setNext(null);} else {node.setNext(first);first = node;}return true;} catch (Exception e) {e.printStackTrace();return false;} finally {rwl.writeLock().unlock();}}/** * 删除一个头结点,并返回头结点 *  * @return * @author xiezc */public T deleteFirstNode() {rwl.writeLock().lock();try {Node tempNode = first;// 此处可以直接用"=="比较,相当于C++中的指针.下同if (first == finalNode) {// 只有一个节点first = tempNode.getNext();finalNode = null;}first = tempNode.getNext();return tempNode.get();} catch (Exception e) {e.printStackTrace();return null;} finally {rwl.writeLock().unlock();}}/** * 获得指定索引的节点<br> * 递归调用:<br> * 1,递归要有停止条件(不然会一直循环下去).<br> * 2:递归的每次返回值要对应与此次的index索引(当然也可以返回错位的索引(index+1)值,但是要小心处理错位的边界情况) *  * @param index *            如果index大于链表的总数量,则返回的是null * @return * @author xiezc */private Node getNodeByIndex(int index) {// 没有判断index<0的情况,因为此方法只被getByIndex()方法调用.rwl.readLock().lock();try {if (index == 0) {// 停止条件return first;}if (index == 1) {// 停止条件return first.getNext();// 返回的都是当前索引的值}Node node = getNodeByIndex(index - 1);// 获得node是index-1对应的值return node.getNext();// 返回的都是当前索引index对应的值} catch (Exception e) {e.printStackTrace();return null;} finally {rwl.readLock().unlock();}}/** * 获得指定索引的节点<br> *  * @param index *            如果index大于链表的总数量,则返回的是null * @return * @author xiezc */public T getByIndex(int index) {if (index < 0)throw new RuntimeException("索引index不能小于零:" + index);return getNodeByIndex(index).get();}/** * 在任意位置之后插入节点 在index的后面插入 *  * @param index *            如果index超出节点数量,则添加在尾节点后面 * @param data * @author xiezc */public boolean add(int index, T data) {if (index < 0)throw new RuntimeException("索引index不能小于零:" + index);if (index == 0) {return addFirstNode(data);}Node node = new Node(data);rwl.writeLock().lock();try {// 获得索引处节点Node current = getNodeByIndex(index);if (current == finalNode) {// 索引处的节点就是最终节点(包括只有一个节点的情况)finalNode.setNext(node);finalNode = node;}if (current == first && finalNode != current) {// 两个节点以上的情况,且current不是最终节点Node next = current.getNext();current.setNext(node);node.setNext(next);}return true;} catch (Exception e) {e.printStackTrace();return false;} finally {rwl.writeLock().unlock();}}/** * 删除任意位置的节点,并且返回删除的节点 *  * @param index *            如果index超出节点数量则返回空的节点,并且没有实现删除 * @return * @author xiezc */public T delete(int index) {if (index < 0)throw new RuntimeException("索引index不能小于零:" + index);if (index == 0) {return deleteFirstNode();}rwl.writeLock().lock();try {// 主要锁住last的值的改变// 获得指定位置处的上一个节点Node last = getNodeByIndex(index - 1);// 当前节点Node current = last.getNext();if (current == null) {// current刚好为空的情况,其实此处可不要,// 因为下面的Node next = current.getNext();会报空指针异常throw new java.lang.ArrayIndexOutOfBoundsException(index);}// 下一个节点Node next = current.getNext();if (next == null) {// 说明要删除的节点刚好是最终节点last.setNext(null);return current.get();}last.setNext(next);return current.get();} catch (Exception e) {e.printStackTrace();return null;} finally {rwl.writeLock().unlock();}}/** * 添加尾节点 *  * @param data * @author xiezc */public boolean addFinalNode(T data) {if (finalNode == null) {return addFirstNode(data);}Node node = new Node(data);rwl.writeLock().lock();try {finalNode.setNext(node);finalNode = node;return true;} catch (Exception e) {e.printStackTrace();return false;} finally {rwl.writeLock().unlock();}}/** * 节点的内部类 * @author xiezc * */class Node {private Node next;private T t;public Node(T t) {this.t = t;}public T get() {return t;}public Node getNext() {return next;}public void setNext(Node next) {this.next = next;}}}


0 0
原创粉丝点击