SpringBoot异步调用方法遇到的问题

Posted 金色的鱼儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot异步调用方法遇到的问题相关的知识,希望对你有一定的参考价值。

启动类加@EnableAsync注解开启异步调用方法功能

在加@Async注解的异步方法里面调用如下代码上传神策数据

 

    public void track(String distinctId,String eventName,Map<String,Object> properties) throws Exception{
        final SensorsAnalytics sa = new SensorsAnalytics(new SensorsAnalytics.ConcurrentLoggingConsumer("D:\myfolder\sensors\access.log"));
        sa.track(distinctId,true,eventName,properties);
        //程序结束前,停止神策分析SDK所有服务
        sa.shutdown();
    }

 

报错信息如下:

java.lang.RuntimeException: fail to write file.
    at com.sensorsdata.analytics.javasdk.SensorsAnalytics$ConcurrentLoggingConsumer$InnerLoggingFileWriter.write(SensorsAnalytics.java:577) ~[SensorsAnalyticsSDK-3.1.15.jar:?]
    at com.sensorsdata.analytics.javasdk.SensorsAnalytics$InnerLoggingConsumer.flush(SensorsAnalytics.java:680) ~[SensorsAnalyticsSDK-3.1.15.jar:?]
    at com.sensorsdata.analytics.javasdk.SensorsAnalytics$ConcurrentLoggingConsumer.flush(SensorsAnalytics.java:463) ~[SensorsAnalyticsSDK-3.1.15.jar:?]
    at com.sensorsdata.analytics.javasdk.SensorsAnalytics$InnerLoggingConsumer.close(SensorsAnalytics.java:686) ~[SensorsAnalyticsSDK-3.1.15.jar:?]
    at com.sensorsdata.analytics.javasdk.SensorsAnalytics$ConcurrentLoggingConsumer.close(SensorsAnalytics.java:463) ~[SensorsAnalyticsSDK-3.1.15.jar:?]
    at com.sensorsdata.analytics.javasdk.SensorsAnalytics.shutdown(SensorsAnalytics.java:1035) ~[SensorsAnalyticsSDK-3.1.15.jar:?]
    at com.huixiaoer.base.service.impl.SensorsAnalyticsServiceImpl.track(SensorsAnalyticsServiceImpl.java:194) ~[classes/:?]
    at com.huixiaoer.base.service.impl.SensorsAnalyticsServiceImpl.bookingSucceed(SensorsAnalyticsServiceImpl.java:135) ~[classes/:?]
    at com.huixiaoer.base.service.impl.SensorsAnalyticsServiceImpl.sensorsAnalyticsBookingSucceed(SensorsAnalyticsServiceImpl.java:114) ~[classes/:?]
    at com.huixiaoer.base.service.impl.SensorsAnalyticsServiceImpl$$FastClassBySpringCGLIB$$c8dce33d.invoke(<generated>) ~[classes/:?]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) ~[spring-aop-5.1.8.RELEASE.jar:5.1.8.RELEASE]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_73]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_73]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_73]
    at java.lang.Thread.run(Thread.java:745) [?:1.8.0_73]
Caused by: java.nio.channels.FileLockInterruptionException
    at sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:1091) ~[?:1.8.0_73]
    at com.sensorsdata.analytics.javasdk.SensorsAnalytics$ConcurrentLoggingConsumer$InnerLoggingFileWriter.write(SensorsAnalytics.java:574) ~[SensorsAnalyticsSDK-3.1.15.jar:?]
    ... 20 more

源码分析:

在如下代码处抛出异常信息“fail to write file.”

            public boolean write(StringBuilder sb) {
                synchronized(this.lockStream) {
                    FileLock lock = null;

                    try {
                        FileChannel channel = this.lockStream.getChannel();
                        lock = channel.lock(0L, 9223372036854775807L, false);
                        this.outputStream.write(sb.toString().getBytes("UTF-8"));
                    } catch (Exception var14) {
                        throw new RuntimeException("fail to write file.", var14);
                    } finally {
                        if (lock != null) {
                            try {
                                lock.release();
                            } catch (IOException var13) {
                                throw new RuntimeException("fail to release file lock.", var13);
                            }
                        }

                    }

                    return true;
                }
            }
!this.isOpen()为true,导致var20为null,(FileLock)var20异常,最后走finally代码块结束。
    public FileLock lock(long var1, long var3, boolean var5) throws IOException {
        this.ensureOpen();
        if (var5 && !this.readable) {
            throw new NonReadableChannelException();
        } else if (!var5 && !this.writable) {
            throw new NonWritableChannelException();
        } else {
            FileLockImpl var6 = new FileLockImpl(this, var1, var3, var5);
            FileLockTable var7 = this.fileLockTable();
            var7.add(var6);
            boolean var8 = false;
            int var9 = -1;

            try {
                this.begin();
                var9 = this.threads.add();
                if (!this.isOpen()) {
                    Object var20 = null;
                    return (FileLock)var20;
                }

                int var10;
                do {
                    var10 = this.nd.lock(this.fd, true, var1, var3, var5);
                } while(var10 == 2 && this.isOpen());

                if (this.isOpen()) {
                    if (var10 == 1) {
                        assert var5;

                        FileLockImpl var11 = new FileLockImpl(this, var1, var3, false);
                        var7.replace(var6, var11);
                        var6 = var11;
                    }

                    var8 = true;
                }
            } finally {
                if (!var8) {
                    var7.remove(var6);
                }

                this.threads.remove(var9);

                try {
                    this.end(var8);
                } catch (ClosedByInterruptException var18) {
                    throw new FileLockInterruptionException();
                }
            }

            return var6;
        }
    }

此问题不知是什么原因???????

 

以上是关于SpringBoot异步调用方法遇到的问题的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot 异步调用方法并接收返回值

Spring boot:使用异步方法作为同步方法

springboot异步注解@Async

从片段中调用分离的异步任务类

springboot 异步调用Async使用方法

springboot异步线程