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对象,然后在循环中重复使用该对象,以避免阻塞主线程


相关文章
|
12月前
每日一道面试题之try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
每日一道面试题之try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
149 0
|
4月前
|
Python
“RuntimeError: main thread is not in main loop“的几种解决方案
“RuntimeError: main thread is not in main loop“的几种解决方案
370 1
|
Java API 开发者
如何触发Thread.sleep抛出的InterruptedException?
其实说来也简单,就是Thread.sleep所在的线程被interrupt了就抛出InterruptedException,但由于历史遗留问题这个十分罕见的情况变成了所有开发者都需要处理的常情,从这个细节的设计可以看出Thread这个类的历史遗留相当严重,其实java早已无法完全兼容旧版本,删除废弃了很多API,但仍然无法改良这些关键部分的设计。
332 0
Java 最常见的面试题:try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
Java 最常见的面试题:try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
|
调度
线程 --- Thread 类的基本用法 old
线程 --- Thread 类的基本用法 old
127 0
线程 --- Thread 类的基本用法 old
|
分布式计算 资源调度 Java
执行MapReduce的Jar包报错:Exception in thread main ExitCodeException exitCode=1
执行MapReduce的Jar包报错:Exception in thread main ExitCodeException exitCode=1
113 0
执行MapReduce的Jar包报错:Exception in thread main ExitCodeException exitCode=1
Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?
sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(线程回到就绪状态,请参考第66题中的线程状态转换图)。
1158 0
调用Thread类的方法:public final String getName() 为什么得到的线程对象的名称默认是:Thread-0、Thread-1、Thread-2、...呢?
调用Thread类的方法:public final String getName()为什么得到的线程对象的名称默认是:Thread-0、Thread-1、Thread-2、...呢? 1 package cn.
1214 0
难道调用ThreadPool.QueueUserWorkItem()的时候,真是必须调用Thread.Sleep(N)吗?
开门见山,下面的例子中通过调用ThreadPool.QueueUserWorkItem(WaitCallback callBack, object state)的方式实现异步调用: 1: class Program 2: { 3: static void Main(...
1122 0