J2V8 error: Invalid V8 thread access

今天使用j2v8在java中执行JavaScript代码时,遇到了一个错误:

Exception in thread "Thread-2" java.lang.Error: Invalid V8 thread access
	at com.eclipsesource.v8.V8Locker.checkThread(V8Locker.java:56)
	at com.eclipsesource.v8.V8.checkThread(V8.java:676)

一个简单的报错示例:

    @Test
    public void test() throws InterruptedException {
        AtomicReference<V8> v8 = new AtomicReference<>();
        new Thread(() -> {
            v8.set(V8.createV8Runtime());
        }).start();
        Thread.sleep(5000);
        v8.get().executeScript("const i = 0;"); // 此处报错
        v8.get().release();
    }

跟踪checkThread方法:

    public void checkThread() {
        if (this.thread != Thread.currentThread()) {
            throw new Error("Invalid V8 thread access");
        }
    }

发现在比对 this.threadThread.currentThread 是否一致,Thread.currentThread 是当前正在执行的线程,而 this.thread 则是V8Runtime创建时的线程,当两个线程不一致时就会抛出这个错误,而 this.thread 存在于V8Locker,v8locker提供两个跟 this.thread 相关的方法,release和acquire:

    public synchronized void acquire() {
        if (this.thread != null && this.thread != Thread.currentThread()) {
            throw new Error("Invalid V8 thread access");
        } else {
            this.thread = Thread.currentThread();
        }
    }

    public synchronized void release() {
        this.checkThread();
        this.thread = null;
    }

所以可以得出解决方案,在创建v8Runtime的线程中释放v8Locker中锁定的线程,然后在使用v8的线程中将当前线程绑定到v8Locker中。

上边报错示例的解决方案:

    @Test
    public void test() throws InterruptedException {
        AtomicReference<V8> v8 = new AtomicReference<>();
        new Thread(() -> {
            V8 v=V8.createV8Runtime();
            v.getLocker().release(); // 在创建runtime的线程中release
            v8.set(v);
        }).start();
        Thread.sleep(5000);
        v8.get().getLocker().acquire();// 在使用runtime的线程中acquire
        v8.get().executeScript("const i = 0;");
        v8.get().release();
    }

注:release和acquire二者缺一不可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值