前言:
  Lua作为解析执行的脚本语言, 往往是易变逻辑编写的首选语言, 尤其是在游戏领域. C/C++和Lua的结合, 往往了标配. 比如Redis, Nginx其对Lua的支持, 也是杠杠的. 当然Lua也可以作为规则引擎中的规则编写语言. 本文对Java调用Lua(Luaj)的实现机制, 做下简单的介绍.

Luaj简介:
  Luaj是Java调用Lua的一种实现方式, 其是构建一个虚拟机解析执行Lua脚本来实现的, 这和Groovy的方式有所不同.
  这是Luaj的官网, http://www.luaj.org/luaj/3.0/README.html.
  它是针对5.2.x的lua版本的解析器, 其Luaj库的编写是通过JavaCC来实现的.

简单示例:
  集合Luaj, 可以通过Maven进行如下配置:

        <dependency><groupId>org.luaj</groupId><artifactId>luaj-jse</artifactId><version>3.0.1</version></dependency>

  Luaj的一个简单的示例程序:

import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;public class TestLuaJ {public static void main(String[] args) {String luaStr = "print 'hello,world!'";Globals globals = JsePlatform.standardGlobals();LuaValue chunk = globals.load(luaStr);chunk.call();}}

  注: Globals继承LuaValue对象,LuaValue对象用来表示在Lua语言的基本数据类型,比如:Nil,Number,String,Table,userdata,Function等。尤其要注意LuaValue也表示了Lua语言中的函数。所以,对于Lua语言中的函数操作都是通过LuaValue来实现的.
  其输出的结果:

hello,world!

原理初探:
  根据官方的说法, Luaj在包装执行具体的Lua代码时, 有三种不同的模式.
  1). 纯脚本解析执行(不选用任何Compiler)
  2). To Lua字节码(LuaC, lua-to-lua-bytecode compiler)
  3). To Java字节码(LuaJC, lua-to-java-bytecode compiler)
  其中LuaC是默认的选用Compiler.
  依据官方的介绍:
  不使用LuaC的方法是, 则不调用如何行:

org.luaj.vm2.compiler.LuaC.install(globals);

  而使用LuaJC的方法, 则是调用

org.luaj.vm2.jse.luajc.LuaJC.install(globals);

  可惜, 笔者在自己测试过程中, 遇到了异常(org.luaj.vm2.LuaError: No compiler.), 好尴尬:
  

性能评估:
  对Lua解析的代码进行简单的性能评估:
  其对同样的逻辑代码:

            int a = 0;for ( int i = 0; i < 10000; i++ ) {a = a + i;}

  执行10000次, 具体对比耗时值.
  整体的测试代码如下:

import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;public class TestLuaJPerf {public static void main(String[] args) {int iterNum = 10000;// *) java 模式运行long beg = System.currentTimeMillis();for ( int j = 0; j < iterNum; j++ ) {int a = 0;for ( int i = 0; i < 10000; i++ ) {a = a + i;}}long end = System.currentTimeMillis();System.out.println(String.format("Java consume: %dms", end - beg));// *) Lua脚本解析执行String luaStr = "a = 0; for i = 0, 10000, 1 do a = a + i; end";Globals globals = JsePlatform.standardGlobals();LuaValue chunk = globals.load(luaStr);beg = System.currentTimeMillis();for ( int i = 0; i < iterNum; i++ ) {chunk.call();}end = System.currentTimeMillis();System.out.println(String.format("Lua consume: %dms", end - beg));}}

  测试结果如下:

Java consume: 10ms
Lua consume: 10249ms

  几乎1000倍的差异, 这个性能对比, 差异有些大, Lua确实慢的不止半点(可能和Luaj的具体实现也有些关系), 因此从这方面来说, Java+Groovy的结合, 比Java+Lua的结合更有优势.

线程安全:
  Luaj中的Globals对象不是线程安全的, 因此最佳实践是每个线程一个Globals对象.
  事实上, 可以采用ThreadLocal的方式来存储该对象.
  因为是对象, 而不是Class, 其和Groovy编译的Script类, 其实现思路是本质区别的.

总结:
  个人对Luaj的认识还是有些肤浅, 没有深入地去研究, 所以可能这边的一些结论可能不准确. 同时Luaj对Lua脚本的支持, 到什么程度, 其实也是一个问号. 不管怎么样, 能对Luaj能有一个初步的认识, 也是好事.

Java调用Lua脚本(热载实现)相关推荐

  1. Java调用Lua(转)

    Java 调用 Lua app发版成本高,覆盖速度慢,覆盖率页低.一些策略上的东西如果能够从服务端控制会方便一些. 所以考虑使用Lua这种嵌入式语言作为策略实现,Java则是宿主语言. 总体上看是一个 ...

  2. java调用Groovy脚本

    一.使用 用 Groovy 的 GroovyClassLoader ,它会动态地加载一个脚本并执行它.GroovyClassLoader是一个Groovy定制的类装载器,负责解析加载Java类中用到的 ...

  3. java使用lua脚本操作 redis_在Redis中使用简单强大的Lua脚本

    Redis分布式锁加锁 前段时间写Redis分布式锁,想着在小灰文章的基础上再总结一下,这样能有更深的印象,顺便把Lua脚本分享一下,如果项目中使用Redis比较多,那么Lua脚本一定是会用到的,因为 ...

  4. java无阻塞执行脚本,JAVA调用Shell脚本-及阻塞的解决方法

    JAVA调用Shell脚本--及阻塞的解决办法 用java调用shell,使用 Process p=Runtime.getRuntime().exec(String[] cmd); Runtime.e ...

  5. Java调用python脚本

    Java调用python脚本 最近也是刚开始学python,所以这里写了一个简单的小方法用Java来调用python脚本.后期再进行更新. 1.Java启动程序的方法 在Java中提供了两种方法来启动 ...

  6. Lua移植到arm上 并实现在arm上 可以让lua脚本调c语言,C语言调用lua脚本

    Lua移植到arm上 并实现在arm上 可以让lua脚本调c语言,C语言调用lua脚本 首先参考http://wiki.chumby.com/index.php?title=Lua&print ...

  7. java 调用python脚本过程_通过Java调用Python脚本

    在进行开发的过程中,偶尔会遇到需要使用Java调用Python脚本的时候,毕竟Python在诸如爬虫,以及科学计算等方面具有天然的优势.最近在工作中遇到需要在Java程序中调用已经写好的Python程 ...

  8. 详解C调用lua脚本效率测试

    详解C调用lua脚本效率测试 C调用lua脚本效率测试是本文要介绍的内容,以下代码以C语言为基准,测试了C调用Lua循环和循环调用Lua的效率.结论是不要频繁地穿越C/Lua边界. #include  ...

  9. java 调用linux 脚本并获取返回值

    大家好,我是烤鸭: 今天分享下java 调用 shell脚本 并获取返回值. 代码实践 String cmd = "df -h"; StringBuffer sb = new St ...

最新文章

  1. Objective C内存管理之理解autorelease------面试题
  2. 正则表达式中$1,$2 ===算是什么意思
  3. Android SharedPreferences 详解 源码解析
  4. Asp.Net Core 发布到IIS
  5. git两个账号切换_多个git账号之间的切换
  6. 如何在家访问公司的文件服务器,企业的共享文件,该怎么高效管理?
  7. 转:vSphere 7简介:混合云的功能和技术
  8. 【Statistics】均值
  9. RTC硬件时钟设置修改【转】
  10. 基因组组装---基因组大小评估(genome survey)
  11. Linux系统中三处profile的作用
  12. 2021中国AI产业10大趋势,一分钟看明白 | WAIC2021
  13. SI522A/SI523带低功耗自动寻卡功能的13.56MHz非接触式读写器芯片
  14. QT打印打印excel
  15. 卸载asterisk
  16. 学习日记day09 ps
  17. 怎样访问远程服务器文件夹,访问远程服务器的共享文件夹
  18. Cookie&Session
  19. Linux 多种方式实现文件共享
  20. oracle版本和驱动ojdbc、jdk版本对应关系

热门文章

  1. 服务器不显示内存条,服务器检测不到内存条
  2. java7 文件_Java SE 7新特性之文件操作(9) - 遍历目录树
  3. MySQL主从、主主、半同步节点架构的的原理及实验总结
  4. 端口被占用,怎么解决?
  5. c++中wstring 和 string的转换
  6. 封装的三级联动及应用
  7. 用命令实现Win7远程桌面关机和重启
  8. 诗与远方:无题(五十五)- 曾经写给妹子的一首诗
  9. ViewPager之使用PagerTabStrip添加标题栏,实现滑动效果
  10. 为啥用mencoder执行格式转换不退出_kindle|什么?calibre还能这么用?