Exception in thread “main“ 主线程异常的解决方法

简介: Exception in thread “main“ 主线程异常的解决方法

项目场景:

       编写氪金游戏,充值抽卡系统的代码,将Scanner类中的创建,和关闭Scanner对象,同时写进了for循环内,导致主线程异常。

问题描述  

       半成品的充值抽卡代码:

import java.util.Scanner;
public class ChouKa {
  private static int yuanShi=0;
  public static void main(String[] args) {
    for(int j=0;j<10;j++) {   
      Scanner sc=new Scanner(System.in);
            //导致BUG的代码
      System.out.println("您是否要充值?(true or false)");
      boolean chongZhi=sc.nextBoolean();
      if(chongZhi==true){
          System.out.println("请输入您的充值金额(元)");
          int money=sc.nextInt();   
          int yuanShiC=money*10;
          System.out.println("邮箱提醒:到账原石"+yuanShiC);
          yuanShi+=yuanShiC;
        }
        System.out.println("原石:"+yuanShi);
        sc.close(); 
            //导致BUG的代码
    }
  }
}

报错如下:  

       编写过程期间,循环充值抽卡代码。第一次输入充值金额,正常运行代码;到第二次运行时,用户不能输入数据,无法运行代码,报错显示,主线程异常。


原因分析:

       在循环中创建和关闭Scanner对象,可能会导致主线程异常


       第一,Scanner是一个阻塞式IO操作,Scanner对象在读取用户输入时,会导致主线程阻塞,程序停止继续执行,流正在等待来自用户的输入,例如从键盘读取输入。在这种情况下,流将阻塞


       第二,用户输入完毕内容,关闭Scanner对象,它也关闭了底层输入源,例如文件或流。如果在循环的下一次迭代中创建了一个新的Scanner对象,但是输入源已经关闭,那么在对新的Scanner对象调用next()时可能会导致抛出异常


       往深了讲,原因是源码中的nextBoolean()方法只读取布尔值,而不使用留在输入缓冲区中的换行字符(\n)。当程序执行到循环的下一个迭代并创建一个新的Scanner对象时,nextInt()方法将读取前一个迭代中留在输入缓冲区中的换行符,而不是等待来自用户的新输入。这将导致程序跳过用户输入的下一个提示,直接进入下一个迭代,从而用户无法输入,代码无法继续运行,主线程发生异常。


      弊端:在循环中反复创建和关闭Scanner对象,相比在循环过程之外进行此操作,计算机操作更复杂,运行内存和时间占用的更多,同时系统反应的会更慢


      因此,在循环中应该避免创建和关闭Scanner对象。最佳实践是在循环外创建Scanner对象,然后在循环中重复使用该对象,以避免阻塞主线程


相关文章
|
Kubernetes 搜索推荐 Linux
Containerd容器镜像管理
Containerd容器镜像管理
|
消息中间件 监控 数据安全/隐私保护
Docker安装部署RabbitMQ & 密码修改 &创建用户及角色
Docker安装部署RabbitMQ & 密码修改 &创建用户及角色
2802 0
|
存储 算法 NoSQL
还分不清 Cookie、Session、Token、JWT?看这一篇就够了
Cookie、Session、Token 和 JWT(JSON Web Token)都是用于在网络应用中进行身份验证和状态管理的机制。虽然它们有一些相似之处,但在实际应用中有着不同的作用和特点,接下来就让我们一起看看吧,本文转载至http://juejin.im/post/5e055d9ef265da33997a42cc
47707 13
|
Java Go Nacos
Spring Cloud Alibaba Nacos配置导入问题解决方案
Spring Cloud Alibaba Nacos配置导入问题解决方案
2260 0
|
JSON 前端开发 数据格式
【前后端异常】http/https post请求 返回415错误状态码的解决方法
【前后端异常】http/https post请求 返回415错误状态码的解决方法
6158 0
|
XML NoSQL Java
Redis - 一篇走心的 RedisUtil 工具类
Redis - 一篇走心的 RedisUtil 工具类
3932 0
Redis - 一篇走心的 RedisUtil 工具类
|
11月前
|
缓存 Java 网络安全
Solr7.4.0报错org.apache.solr.common.SolrException
在使用 Solr 7.4.0 时,`org.apache.solr.common.SolrException` 错误可能由多种原因引起,包括配置文件错误、核心未加载、权限问题、Java 环境问题、依赖库冲突和网络配置问题。通过检查配置文件、确保正确的权限、验证Java环境、解决依赖库冲突和检查网络配置,可以有效解决这些问题。结合日志文件、管理控制台和调试模式,可以快速定位和解决错误,确保 Solr 系统的稳定运行。
511 1
|
SQL 数据库
达梦数据库阻塞死锁及解锁
【10月更文挑战第6天】本文介绍了在达梦数据库中模拟和解决死锁的方法。首先通过创建表并插入数据但不提交事务,模拟了阻塞情况;接着利用V$TRXWAIT和V$SESSIONS视图查询阻塞信息,并通过SP_CLOSE_SESSION函数解决阻塞。最后讨论了死锁的成因及避免策略,强调了正确管理事务的重要性。
|
缓存 监控 安全
Spring AOP 详细深入讲解+代码示例
Spring AOP(Aspect-Oriented Programming)是Spring框架提供的一种面向切面编程的技术。它通过将横切关注点(例如日志记录、事务管理、安全性检查等)从主业务逻辑代码中分离出来,以模块化的方式实现对这些关注点的管理和重用。 在Spring AOP中,切面(Aspect)是一个模块化的关注点,它可以跨越多个对象,例如日志记录、事务管理等。切面通过定义切点(Pointcut)和增强(Advice)来介入目标对象的方法执行过程。 切点是一个表达式,用于匹配目标对象的一组方法,在这些方法执行时切面会被触发。增强则定义了切面在目标对象方法执行前、执行后或抛出异常时所
16726 4
|
SQL Java 数据库连接
成功解决:was not registered for synchronization because synchronization is not active
这篇文章是关于解决Mybatis在同步过程中出现"was not registered for synchronization because synchronization is not active"错误的技术博客。
成功解决:was not registered for synchronization because synchronization is not active