按照上一篇中提到的思路,最后问题的焦点在于:怎样快速找到tmp中的为1的bit位在x中的实际位置。这样在计算N值的同时将每一位的权值与索引位置的关系用数组对照起来,最后只需要在遍历tmp的值为1的bit位时作相应的加权累加即可。
也综合评论中提到的递归方案,重新补充了各个方案的代码和性能测试代码。
见“方案1”的代码处:
按照上一篇中提到的思路,最后问题的焦点在于:怎样快速找到tmp中的为1的bit位在x中的实际位置。这样在计算N值的同时将每一位的权值与索引位置的关系用数组对照起来,最后只需要在遍历tmp的值为1的bit位时作相应的加权累加即可。
也综合评论中提到的递归方案,重新补充了各个方案的代码和性能测试代码。
见“方案1”的代码处:
给定一个long型常量,其值为x,给定long型变量a,要求a & x 的取值集合,结果放入ArrayList中。
思路,x先转换为bit数组,得出其中元素值为1的总数为n,则所有取值的总数为2的n次方,记为N。
在0~N的闭区间中,依次取出各个数值,记为tmp,将tmp也转换为bit数组,依次遍历x的每一个bit位,当x的bit位为1时,到tmp中去取出相应的bit位,如果也为1,则将该位为1时,其他所有位为0时所代表的数值累加到结果中。
遍历完所有的bit位后,得到的结果即为所需要的数值。
整个思路有点复杂,性能也不高,从数值本身的与或运算上面着手,肯定还有更简单的方法。
代码:
照着这里的简单教程(http://www.kerneltravel.net/?page_id=8)编写了第一个内核模块,对中断和内核模块注册形成了简单的认识。
Makefile文件:
# Makefile2.6
obj-m += first.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/kernels/$(LINUX_KERNEL)
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
首先编写Java类,用于调用C++库导出的方法:
public class TestMain
{
public native boolean printInfo();
public native int getNum();
public native void setNum(int num);
jstatd -J-Djava.security.policy=jstatd.all.policy -p 10423
注意jstatd.all.policy文件的绝对路径和jstatd可执行文件的路径要一致。
对于jmx连接:
service:jmx:rmi:///jndi/rmi://172.16.128.80:1099/JMXConnector
关于Mbean和JMX
基于RMI实现的JMX动态管理java程序运行时的实例的属性的接口标准。
用 MBeanServerKernelBridge 和 MBeanGBeanBridge 连接 Geronimo 与 JMX
Geronimo 提供了几个类来弥补 Geronimo GBean 框架与 JMX MBean 框架之间的差距。MBeanServerKernelBridge 类将载入 Geronimo 的每一个 GBean 注册为相关联 MBeanServer 实例中的一个 MBean。该行为使得使用 Geronimo 公开 MBeans 的过程只是将其封装在 GBean 中,然后使用 Geronimo 内核注册 GBean。
内核启动过程中,在 MBeanServerKernelBridge 实例启动时,将检索内核注册的所有 GBeans 并将它们转换为 MBeans。这些 MBeans 是动态 MBean,它们以 MBeanGBeanBridge 实例的形式维护对 Geronimo 内核的引用和存储在每个 GBean 的 GBeanInfo 引用中的信息。
因为 MBeanServerKernelBridge 实例是由 Geronimo 内核注册为 GBean 的,所以只要注册新的 GBean,该 GBean 就会自动注册为 LifecycleAdapter 实现,以接收加载事件和卸载事件。在发生加载和卸载事件时,MBeanServerKernelBridge 使用 MBeanServer 将每个相关联的 GBean 注册和注销为一个 MBean,以确保 JMX 感知客户端提供 Geronimo 和 Geronimo 内核当前状态的精确视图。