欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

工作的几个tip

程序员文章站 2022-03-10 19:17:03
...

1、如果用java6的ScriptEngineManager来调用JRuby,并且脚本使用到了Ruby的标准库(比如我用到了YAML库),如果没有正确设置,是会找不到标准库的。通过打印$:变量可以看到文件的加载路径,比如在某台机器上的打印的结果:
   puts $:
   输出:
.
/root/.jruby/lib/ruby/site_ruby/1.8
/root/.jruby/lib/ruby/site_ruby
/root/.jruby/lib/ruby/1.8
/root/.jruby/lib/ruby/1.8/java
lib/ruby/1.8
......略

显然,默认会到当前用户的主目录下寻找.jruby隐藏目录,将此目录作为Ruby的安装目录,因此,可以在~user/.jruby放置一个jruby实现,一劳永逸地解决问题,不然就要自己手工添加完整的路径到$:变量中。

2、nio的临时selector的使用,了解grizzly的都知道,Grizzly框架有一个比较与众不同的地方在于使用临时selector注册channel进行读或者写。这个带来什么好处呢?一个是,通常我们可能将read派发到其他线程中去,如果一次没有读完,那么就得继续注册OP_READ到主selector上;注意,nio在一些平台上有个问题,就是SelectionKey.interestOps方法跟Selector.select方法会有并发冲突,产生奇怪的现象,因此,你会看到大多数的nio框架都会保证SelectionKey.interestOps跟Selector.select的调用在同一个线程;在没有读完继续注册这个场景下,免不了线程间的context switch,如果采用一个临时selector注册并读取,就可以避免这个切换开销。另外,对于write调用,通常你可能这样写:

while (byteBuffer.hasRemaining()) {
  int len = socketChannel.write(byteBuffer);
  if (len < 0){
   throw new EOFException(); 
  }
}
 


   在负载比较高的时候,write返回0的次数会越来越多,while循环将空耗多次导致CPU占用偏高,这个问题在win32上比较严重,同样可以采用临时selector的解决(Cindy2.x是留在队列,等待下次写)。下例是采用临时Selector进行读的例子:

 Selector readSelector = SelectorFactory.getSelector();
                SelectionKey tmpKey = sc.register(readSelector,
                        SelectionKey.OP_READ);
                tmpKey.interestOps(tmpKey.interestOps() | SelectionKey.OP_READ);
                int code = readSelector.select(1000);
                tmpKey.interestOps(tmpKey.interestOps()
                        & (~SelectionKey.OP_READ));
                if (code > 0) {
                    do {
                        n = sc.read(in);
                    } while (n > 0 && in.hasRemaining());
                    in.flip();
                    decode();
                    in.compact();
                }
                SelectorFactory.returnSelector(readSelector);
 

<!---->      这样的方式,某种意义上可以认为是non-blocking模式下的阻塞读,在网络条件稳定的情况下(比如内网),能带来比较高的效率。

3、spymemcached ,是另一个memcached的java client实现,采用nio。最近遇到的问题是它跟原来的MemcachedClient 的兼容问题,用它去操作MemcachedClient存储的数据。spymemcached是通过Transcoder来实现序列化,Transcoder的WhalinTranscoder实现类兼容了Greg Whalin的MemcachedClient:

private Transcoder whalinTranscoder = new WhalinTranscoder();


Future<Object> f = memcachedClient.asyncGet(id, whalinTranscoder);
 


   各个方法都有重载的版本用以指定Transcoder。