Java带缓存的单向链表-线程安全

开发原因

ArrayList太重,线程还不安全

在一些队列处理的时候,ArrayList有点麻烦,还比较占内存,还没缓存,又得再加个缓存队列

所以就开发了这个

轻量级,线程安全,带缓存!nice!!

源码

java 复制代码
package com.geom.queue;

public class SinglyLinked<T>
{
	private Object _lock = new Object();
	
	private int _length = 0;
	
	private SinglyLinkedNode<T> _head = new SinglyLinkedNode<T>();
	private SinglyLinkedNode<T> _end = null;
	
	private int _cacheMax = 0;
	private SinglyLinked<Object> _cache = null;
	
	public SinglyLinked()
	{
	}
	
	/**
	 * 0表示不缓存SinglyLinkedNode
	 * @param cacheMax
	 */
	public SinglyLinked(int cacheMax)
	{
		_cacheMax = cacheMax;
		if(_cacheMax > 0)
		{
			_cache = new SinglyLinked<Object>();
		}
	}
	
	public int length()
	{
		return _length;
	}
	
	@SuppressWarnings("unchecked")
	public void push( T value )
	{
		SinglyLinkedNode<T> node = null;
		if( _cache != null )
		{
			Object obj = _cache.pop();
			if( obj != null ) node = (SinglyLinkedNode<T>)obj;
		}
		if( node==null ) node = new SinglyLinkedNode<T>();
		node.value = value;
		node.next = null;
		
		synchronized (_lock)
		{
			if(_end==null)
				_head.next = node;
			else _end.next = node;
			
			_end = node;
			_length++;
		}
	}
	
	public T pop()
	{
		synchronized (_lock)
		{
			if( _head.next != null )
			{
				T v = _head.next.value;
				if( _head.next==_end )
				{
					_end = null; //防止尾巴自己成一个链表
				}
				if( _cache != null )
				{
					if( _cache._length < _cacheMax )
					{
						_head.next.value = null;
						_cache.push(_head.next);
					}
				}
				_head.next = _head.next.next;

				_length--;
				
				return v;
			}
		}
		return null;
	}
	
	private SinglyLinkedNode<T> _current = null;
	public void resetFor()
	{
		synchronized (_lock)
		{
			_current = _head.next;
		}
	}
	
	/**
	 * 跟resetFor一起使用
	 * @return
	 */
	public T next()
	{
		synchronized (_lock)
		{
			if( _current != null )
			{
				T v = _current.value;
				_current = _current.next;
				
				return v;
			}
		}
		return null;
	}
	
	private static class SinglyLinkedNode<T>
	{
		SinglyLinkedNode<T> next = null;
		public T value = null;
		
		public SinglyLinkedNode()
		{
		}
	}
}

测试代码

java 复制代码
public static void main(String[] args)
{
	SinglyLinked<Integer> link = new SinglyLinked<Integer>(10);
	
	link.push(1);
	link.push(2);
	
	link.resetFor();
	Integer v;
	
	while( (v = link.next()) != null )
	{
		System.out.println(v);
	}
	
	new Thread(new Runnable()
	{
		private int _v = 0;
		@Override
		public void run()
		{
			while(true)
			{
				link.push(_v++);
				try
				{
					Thread.sleep(1);
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		}
	}).start();
	
	new Thread(new Runnable()
	{
		@Override
		public void run()
		{
			while(true)
			{
				System.out.println(link.length() + ": " + link.pop());
				try
				{
					Thread.sleep(1);
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
		}
	}).start();
}
相关推荐
青石路3 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
像我这样帅的人丶你还6 小时前
Java 后端详解(五):Redis 缓存
java·后端·全栈
plainGeekDev8 小时前
GreenDAO → Room
android·java·kotlin
亦暖筑序13 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
敲代码的彭于晏14 小时前
Bean 生命周期完全图解:前端同学也能看懂的 Spring 核心机制
java·前端·后端
plainGeekDev15 小时前
ButterKnife → ViewBinding
android·java·kotlin
像我这样帅的人丶你还1 天前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩1 天前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构
tntxia1 天前
Mybatis的日志输入
java
亦暖筑序1 天前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式