各种类封装,各种接口!!!!!!!!!!!!!!
1.单例 private static Test test;
public static Test instance() {
if (null == client) {
synchronized (SubClient.class) {
if (null == client) {
client = new SubClient();
}
}
}
return client;
}
Class A
{
B //类级别
public A() //new A的时候,只执行一次
{
}
public B init() //只调用一次
{
}
public C get() //方法级别
{
c=new C
}
}
2.使用map进行注册管理
--》收到netty server发过来的数据,根据消息的类Class,寻找对应的处理processor,进行处理
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (LOG.isDebugEnabled()) {
LOG.debug("proto handler: " + ctx.channel().remoteAddress() + ">>" + msg);
}
IProtoProcessor<Object> processor = RegManager.getProcessor(msg.getClass());
if (processor != null) {
processor.receive(ctx, msg);
}
ctx.fireChannelRead(msg);
}
public interface IProtoProcessor<T>
{
public void receive(ChannelHandlerContext ctx, T msg);
}
3.队列--生产者消费者
BlockingQueue
https://www.cnblogs.com/tjudzj/p/4454490.html
常用的队列主要有以下两种:(当然通过不同的实现方式,还可以延伸出很多不同类型的队列,DelayQueue就是其中的一种)
先进先出(FIFO):先插入的队列的元素也最先出队列,类似于排队的功能。从某种程度上来说这种队列也体现了一种公平性。
后进先出(LIFO):后插入队列的元素最先出队列,这种队列优先处理最近发生的事件。
多线程环境中,通过队列可以很容易实现数据共享,比如经典的“生产者”和“消费者”模型中,通过队列可以很便利地实现两者之间的数据共享。假设我们有若干生产者线程,另外又有若干个消费者线程。如果生产者线程需要把准备好的数据共享给消费者线程,利用队列的方式来传递数据,就可以很方便地解决他们之间的数据共享问题。但如果生产者和消费者在某个时间段内,万一发生数据处理速度不匹配的情况呢?理想情况下,如果生产者产出数据的速度大于消费者消费的速度,并且当生产出来的数据累积到一定程度的时候,那么生产者必须暂停等待一下(阻塞生产者线程),以便等待消费者线程把累积的数据处理完毕,反之亦然
4.同步
private AtomicBoolean threadStarted = new AtomicBoolean(false);
if (threadStarted.compareAndSet(false, true)) { //查看线程是否启动,保证只启动一个线程
this.sendThread = new AThread(ctx);
this.sendThread.start();
this.userProcessThread = new BThread(ctx);
this.userProcessThread.start();
} else {
this.sendThread.resetCtx(ctx);
this.userProcessThread.resetCtx(ctx);
}
private AtomicReference<ChannelHandlerContext> ctx = new AtomicReference<>();
我们一般会使用AtomicReference的CAS保证原子性,但是它是通过比较引用是否相同判断是否可以更新。
atomicReference1.compareAndSet(100, 200);
atomicReference1.compareAndSet(100, 300);
atomicReference1.compareAndSet(200, 400);
atomicReference1.compareAndSet(300, 500);
System.out.println(atomicReference1.get());
初始值为常量池中的100,第一步中100会先转成Integer.valueOf(100),这个对象其实就是常量池中的100,第一步相同可以更新为200。
再向后面Integer.valueOf(200) != Integer.valueOf(200),所以以后都不等,最终结果为200.
赋值操作不是线程安全的。若想不用锁来实现,可以用AtomicReference<V>这个类,实现对象引用的原子更新。
使用场景:一个线程使用student对象,另一个线程负责定时读表,更新这个对象。那么就可以用AtomicReference这个类。
private AtomicLong idGen = new AtomicLong(0L);
idGen.getAndIncrement() //产生累加的数