Disruptor预备知识

本文介绍了Java中并发编程的基础知识,包括使用Unsafe类进行内存直接操作的方法、Condition接口的用法、计算以2为底的对数的两种方式、获取数组元素偏移量和大小的技巧、AtomicReferenceFieldUpdater类的应用、Arrays.copyOf()方法的使用及可变参数的介绍。

1.sun.misc.Unsafe 示例

package com.java.magic.part4.exception;

import java.lang.reflect.Field;

import sun.misc.Unsafe;

class Target{
	
	int intParam = 3;
	
	long longParam;
	
	String strParam;
	
	String strParam1;
}

public class UnsafeTest {
	
	private static Unsafe unsafe;
	
	static{
		try {
			//通过反射获取theUnsafe
			Field field = Unsafe.class.getDeclaredField("theUnsafe");
			field.setAccessible(true);
			unsafe = (Unsafe)field.get(null);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws Exception {
		
		Class clazz = Target.class;
		Field[] fields = clazz.getDeclaredFields();
		System.out.println("fieldNameeeee:fieldOffset");
		for(Field f : fields){
			//获取属性偏移量,可以通过这个偏移量给属性设值
			System.out.println(f.getName()+" : "+unsafe.objectFieldOffset(f));
		}
		System.out.println("--------------------------------");
		Target target = new Target();
		Field intParam = clazz.getDeclaredField("intParam");
		int a = (Integer) intParam.get(target);
		System.out.println("intParam原始值:"+a);
		long intParamOffset = unsafe.objectFieldOffset(intParam);
		System.out.println("intParam实例变量偏移量:"+intParamOffset);
		//intParam实例变量偏移量是offset 原始值是3,我们要改成10
		System.out.println(unsafe.compareAndSwapInt(target, intParamOffset, 3, 10));
		System.out.println("intParam改变之后的值:"+target.intParam);
		
		System.out.println("--------------------------------");
		//这个时候已经改为10了,所以会返回false  
        System.out.println(unsafe.compareAndSwapInt(target, intParamOffset, 3, 10)); 
        
        System.out.println("--------------------------------");
        Field strParam = clazz.getDeclaredField("strParam");
        String str = (String) strParam.get(target);
        System.out.println("strParam原始值:"+str);
        long strParamOffset = unsafe.objectFieldOffset(strParam);
        System.out.println("strParam实例变量的偏移量是:"+strParamOffset);
        System.out.println(unsafe.compareAndSwapObject(target, strParamOffset, null, "5")); 
		System.out.println("strParam改变之后的值:"+target.strParam);
		
		
	}
	

}

 

2.java.util.concurrent.locks.Condition

package com.java.magic.part4.exception;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class NumberWrapper{
	
	public int value = 1;
}

public class ConditionTest {
	
	public static void main(String[] args) {
		
		//初始化可重入锁
		final Lock lock = new ReentrantLock();
		
		//第一个条件当屏幕上输出到3
		final Condition reachThreeCondition = lock.newCondition();
		
		//第二个条件当屏幕上输出到6
		final Condition reachSixCondition = lock.newCondition();
		
		//NumberWrapper只是为了封装一个数字,一边可以将数字对象共享
		final NumberWrapper num = new NumberWrapper();
		
		//初始化A线程,这个线程输出123, 789
		Thread threadA = new Thread(new Runnable() {
			
			@Override
			public void run() {
		        //reachThreeCondition.signal(); 这个东西需要放到lock.lock()和lock.unlock()之间使用
				lock.lock();
				try{
					while(num.value <= 3){
						System.out.println(Thread.currentThread().getName()+" : "+(num.value++));
					}
					reachThreeCondition.signal();//唤醒由reachThreeCondition.await()造成阻塞的线程
				} finally{
					lock.unlock();
				}
				
				
				lock.lock();
				try {
					if(num.value < 6){
						reachSixCondition.await();//阻塞当前线程,直到reachSixCondition.signal()唤醒当前线程
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				} finally{
					lock.unlock();
				}
				
				while(num.value <= 9){
					System.out.println(Thread.currentThread().getName()+" : "+(num.value++));
				}
				
			}
		});
		
		//初始化B线程,这个线程输出456
		Thread threadB = new Thread(new Runnable() {
			
			@Override
			public void run() {
			    lock.lock();
			    try{
			    	 if(num.value < 3){
						 reachThreeCondition.await();//阻塞当前线程,直到reachThreeCondition.signal()唤醒当前线程
		             }
			    } catch(Exception e){
			    	
			    } finally{
			    	lock.unlock();
			    }

			    lock.lock();
			    try{
			    	while(num.value <= 6){
						System.out.println(Thread.currentThread().getName()+" : "+(num.value++));
					}
			    	reachSixCondition.signal();//唤醒由reachSixCondition.await()造成阻塞的线程
			    } finally{
			    	lock.unlock();
			    }
			    
				
			}
		});
		
		//
		threadA.start();
		threadB.start();
		
		
	}

}

3.求以2为低N的对数

方法1(推荐)

	public static int log2(int i)
    {
        int r = 0;
        while ((i >>= 1) != 0)
        {
            ++r;
        }
        return r;
    }

 方法2

Math.log(N)/Math.log(2)

 

 

4.获取long类型的数组中首个元素的偏移量和每个元素的所占内存空间大小

public static void unsafeTest() throws Exception{
	     Unsafe unsafe = getUnsafe();
	     
	     //获取long类型的数组中首个元素的偏移量
	     int offset = unsafe.arrayBaseOffset(long[].class);
	     //获取long类型的数组中为每个元素分配的内存空间大小
	     int scale = unsafe.arrayIndexScale(long[].class);
	     System.out.println("offset:"+offset+", scale:"+scale);
	     
	     long[] buffer = new long[10];
	     //unsafe
	     unsafe.putOrderedLong(buffer, offset+	16, 1003l);
	     
	     
	     System.out.println(buffer[2]);
	     
	     
	    
	}

 

 

5.AtomicReferenceFieldUpdater类

package com.java.magic.part4.exception;

import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;


import sun.misc.Unsafe;

public class Test {
	
	protected volatile String[] names = new String[0];

	/**
	 * 参考:http://huangyunbin.iteye.com/blog/1944153
	 * AtomicReferenceFieldUpdater<AbstractSequencer, Sequence[]> SEQUENCE_UPDATER =
		        AtomicReferenceFieldUpdater.newUpdater(AbstractSequencer.class, Sequence[].class, "gatingSequences");
	 */
	public static void AtomicReferenceFieldUpdaterTest() throws Exception{
		
		AtomicReferenceFieldUpdater<Test, String[]> updater = AtomicReferenceFieldUpdater.newUpdater(Test.class, String[].class, "names");
		
		Test test = new Test();
	    System.out.println(test.names);
		System.out.println(updater.get(test)); //获取对象里面的成员变量,说明获取的是Test中的names
	}
}

 

6.Arrays.copyOf() 方法

	public static void arraysCopyOf(){
		
		String[] names = {"高伟刚","高红成","高显兵"};
		System.out.println("names length:"+names.length);
		String[] newnames = Arrays.copyOf(names, 5);
		System.out.println("newnames length:"+newnames.length);
		for(int i =0 ; i< newnames.length; i++){
			System.out.println(newnames[i]);
		}
	}

 

7.jdk5新特性:可变参数

/*
	 * 如果传的是数组的话,那么names的长度是数据的大小
	 */
	public static void paramTest(String... names){
		
		System.out.println(names.length);
	}

 

 

 

 

 

### Disruptor框架介绍 Disruptor 是一种高性能的并发编程框架,专为低延迟应用设计。该框架通过创新性的环形缓冲区(Ring Buffer)结构实现了高效的生产者-消费者模型[^1]。 #### 高效的消息传递机制 在启动 `start` 方法前,需先配置好消息处理逻辑并将消费者注册到 Disruptor 中。这种预先设定的方式有助于减少运行时开销,提高吞吐量。与传统的基于锁的数据结构不同的是,Disruptor 实现了一种无锁化的并行算法,从而显著降低了线程间的竞争和上下文切换带来的额外负担[^2]。 #### RingBuffer工作原理 核心组件之一就是 RingBuffer, 它负责存储待处理的任务项。为了支持快速存取操作,每一个槽位都预分配好了内存空间,并由一个称为 Sequence 的计数器跟踪当前可用位置。当有新的数据到来时,生产者会请求下一个空闲索引;而消费者则依据自身的进度读取消息完成业务逻辑后更新自己的消费序号[^4]。 ```java // 创建工厂类用于实例化事件对象 public class LongEventFactory implements EventFactory<LongEvent> { @Override public LongEvent newInstance() { return new LongEvent(); } } ``` ### 使用场景详解 适用于那些对实时性和响应速度有着极高要求的应用领域: - **金融交易系统**:毫秒级甚至更低级别的延迟能够带来竞争优势; - **高频数据分析平台**:能够迅速解析大量日志或者市场行情变动信息; - **分布式缓存集群间同步**:确保各个节点之间状态的一致性的同时保持高效通信效率; - **游戏服务器端架构优化**:提升玩家体验流畅度,降低网络抖动影响[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值