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();
}
相关推荐
Moshow郑锴4 分钟前
实战分享:用 SpringBoot-API-Scheduler 构建 API 监控闭环 —— 从断言验证到智能警报
java·spring boot·后端·任务调度
掘我的金22 分钟前
播放器最怕“首帧黑屏”?我给 LibreTV 加了一套缓冲与预加载策略
java
低客的黑调39 分钟前
为你的项目选择一个适合的[垃圾收集器]
java·jvm·算法
雨中飘荡的记忆1 小时前
优惠券系统设计与实现
java
1***t8271 小时前
将 vue3 项目打包后部署在 springboot 项目运行
java·spring boot·后端
芬加达1 小时前
leetcode34
java·数据结构·算法
__万波__1 小时前
二十三种设计模式(三)--抽象工厂模式
java·设计模式·抽象工厂模式
better_liang1 小时前
每日Java面试场景题知识点之-线程池配置与优化
java·性能优化·面试题·线程池·并发编程
q***2511 小时前
Windows操作系统部署Tomcat详细讲解
java·windows·tomcat
N***H4861 小时前
使用Springboot实现MQTT通信
java·spring boot·后端