1. hello world
> print("Hello World!")
我们也可以将代码修改为如下形式来执行脚本(在开头添加:#!/usr/local/bin/lua):
#!/usr/local/bin/lua
print("Hello World!")
print("www.runoob.com")
运行
./hello.lua
Hello World!
www.runoob.com
2. 数据类型
3. 变量
Lua 中的变量全是全局变量,那怕是语句块或是函数里,除非用 local 显式声明为局部变量。
-- test.lua 文件脚本
a = 5 -- 全局变量
local b = 5 -- 局部变量
function joke()
c = 5 -- 全局变量
local d = 6 -- 局部变量
end
joke()
print(c,d) --> 5 nil
do
local a = 6 -- 局部变量
b = 6 -- 对局部变量重新赋值
print(a,b); --> 6 6
end
print(a,b) --> 5 6
a, b, c = 0, 1
print(a,b,c) --> 0 1 nil
a, b = a+1, b+1, b+2 -- value of b+2 is ignored
print(a,b) --> 1 2
a, b, c = 0
print(a,b,c) --> 0 nil nil
4. 循环
while循环
a=10
while( a < 20 )
do
print("a 的值为:", a)
a = a+1
end
for循环
- 数值循环 , f(x)只会在循环开始前执行一次
#!/usr/local/bin/lua
function f(x)
print("function")
return x*2
end
for i=1,f(5)
do
print(i)
end
结果:
function
1
2
3
4
5
6
7
8
9
10
- 泛型循环
i是数组索引值,v是对应索引的数组元素值。ipairs是Lua提供的一个迭代器函数,用来迭代数组。
--打印数组a的所有值
a = {"one", "two", "three"}
for i, v in ipairs(a)
do
print(i, v)
end
5. 判断
--[ 定义变量 --]
a = 100;
--[ 检查条件 --]
if( a < 20 )
then
--[ if 条件为 true 时执行该语句块 --]
print("a 小于 20" )
else
--[ if 条件为 false 时执行该语句块 --]
print("a 大于 20" )
end
print("a 的值为 :", a)
结果
a 大于 20
a 的值为 : 100
6. 数组
array = {}
for i= -2, 2 do
array[i] = i *2
end
for i = -2,2 do
print(array[i])
end
结果
-4
-2
0
2
4
7. 迭代器
格式:
for k, v in pairs(t) do
print(k, v)
end
array = {"Google", "Runoob"}
for key,value in ipairs(array)
do
print(key, value)
end
8.Java中使用Lua脚本整合redis
1. pom
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
2. 工具类
package com.*.utils;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class FileUtils {
//无成员变量 --- 无状态
public static String getScript(String fileName){
String path = FileUtils.class.getClassLoader().getResource(fileName).getPath();
return readFileByLines(path);
}
public static String readFileByLines(String fileName) {
FileInputStream file = null;
BufferedReader reader = null;
InputStreamReader inputFileReader = null;
String content = "";
String tempString = null;
try {
file = new FileInputStream(fileName);
inputFileReader = new InputStreamReader(file, "utf-8");
reader = new BufferedReader(inputFileReader);
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
content += tempString;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
return content;
}
public static void main(String[] args) {
String path = FileUtils.class.getClassLoader().getResource("unlock.lua").getPath();
String script = FileUtils.readFileByLines(path);
System.out.println(script);
}
}
3. 调用方式
这里是redis实现分布式锁的解锁场景,调用lua脚本保证原子性。
package com.*.lock;
import com.*.utils.FileUtils;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
@Service
public class RedisLock implements Lock {
private static final String KEY = "LOCK_KEY";
@Resource
private JedisConnectionFactory factory;
private ThreadLocal<String> local = new ThreadLocal<>();
@Override
//阻塞式的加锁
public void lock() {
//1.尝试加锁
if(tryLock()){
return;
}
//2.加锁失败,当前任务休眠一段时间
try {
Thread.sleep(10);//性能浪费
} catch (InterruptedException e) {
e.printStackTrace();
}
//3.递归调用,再次去抢锁
lock();
}
@Override
//阻塞式加锁,使用setNx命令返回OK的加锁成功,并生产随机值
public boolean tryLock() {
//产生随机值,标识本次锁编号
String uuid = UUID.randomUUID().toString();
Jedis jedis = (Jedis) factory.getConnection().getNativeConnection();
/**
* key:我们使用key来当锁
* uuid:唯一标识,这个锁是我加的,属于我
* NX:设入模式【SET_IF_NOT_EXIST】--仅当key不存在时,本语句的值才设入
* PX:给key加有效期
* 1000:有效时间为 1 秒
*/
String ret = jedis.set(KEY, uuid,"NX","PX",1000);
//设值成功--抢到了锁
if("OK".equals(ret)){
local.set(uuid);//抢锁成功,把锁标识号记录入本线程--- Threadlocal
return true;
}
//key值里面有了,我的uuid未能设入进去,抢锁失败
return false;
}
//正确解锁方式
public void unlock() {
//读取lua脚本
String script = FileUtils.getScript("unlock.lua");
//获取redis的原始连接
Jedis jedis = (Jedis) factory.getConnection().getNativeConnection();
//通过原始连接连接redis执行lua脚本
jedis.eval(script, Arrays.asList(KEY), Arrays.asList(local.get()));
}
//-----------------------------------------------
@Override
public Condition newCondition() {
return null;
}
@Override
public boolean tryLock(long time, TimeUnit unit)
throws InterruptedException {
return false;
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
}
5. lua文件
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
6. 业务代码