如何终止java线程

2023-11-20

   终止线程的三种方法 

    有三种方法可以使终止线程。 

    1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。 

    2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。 

    3.  使用interrupt方法中断线程。 
1. 使用退出标志终止线程 

    当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的。如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想让循环永远运行下去,可以使用while(true){……}来处理。但要想使while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环是否退出。下面给出了一个利用退出标志终止线程的例子。 

package chapter2; 

public class ThreadFlag extends Thread 

    public volatile boolean exit = false; 

    public void run() 
    { 
        while (!exit); 
    } 
    public static void main(String[] args) throws Exception 
    { 
        ThreadFlag thread = new ThreadFlag(); 
        thread.start(); 
        sleep(5000); // 主线程延迟5秒 
        thread.exit = true;  // 终止线程thread 
        thread.join(); 
        System.out.println("线程退出!"); 
    } 



    在上面代码中定义了一个退出标志exit,当exit为true时,while循环退出,exit的默认值为false.在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值, 

    2. 使用stop方法终止线程 

    使用stop方法可以强行终止正在运行或挂起的线程。我们可以使用如下的代码来终止线程: 

thread.stop(); 


    虽然使用上面的代码可以终止线程,但使用stop方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果,因此,并不推荐使用stop方法来终止线程。 

    3. 使用interrupt方法终止线程 

    使用interrupt方法来终端线程可分为两种情况: 

    (1)线程处于阻塞状态,如使用了sleep方法。 

    (2)使用while(!isInterrupted()){……}来判断线程是否被中断。 

    在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。下面的代码演示了在第一种情况下使用interrupt方法。 

package chapter2; 

public class ThreadInterrupt extends Thread 

    public void run() 
    { 
        try 
        { 
            sleep(50000);  // 延迟50秒 
        } 
        catch (InterruptedException e) 
        { 
            System.out.println(e.getMessage()); 
        } 
    } 
    public static void main(String[] args) throws Exception 
    { 
        Thread thread = new ThreadInterrupt(); 
        thread.start(); 
        System.out.println("在50秒之内按任意键中断线程!"); 
        System.in.read(); 
        thread.interrupt(); 
        thread.join(); 
        System.out.println("线程已经退出!"); 
    } 



    上面代码的运行结果如下: 

    在50秒之内按任意键中断线程! 

    sleep interrupted 
    线程已经退出! 


    在调用interrupt方法后, sleep方法抛出异常,然后输出错误信息:sleep interrupted. 

    注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。因此,while (!isInterrupted())也可以换成while (!Thread.interrupted())。 

如何停止JAVA线程

如何停止java的线程一直是一个困恼我们开发多线程程序的一个问题。这个问题最终在Java5的java.util.concurrent中得到了回答:使用interrupt(),让线程在run方法中停止。

简介

在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start()stop()stop(Throwable) and suspend()destroy() and resume()。通过这些方法,我们可以对线程进行方便的操作,但是这些方法中,只有start()方法得到了保留。

在Sun公司的一篇文章《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中详细讲解了舍弃这些方法的原因。那么,我们究竟应该如何停止线程呢?

建议使用的方法

在《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中,建议使用如下的方法来停止线程:

    private volatile Thread blinker; 
    public void stop() { 
        blinker = null
    } 
    public void run() { 
        Thread thisThread = Thread.currentThread(); 
        while (blinker == thisThread) { 
            try { 
                thisThread.sleep(interval); 
            } catch (InterruptedException e){ 
            } 
            repaint(); 
        } 
    }

关于使用volatile关键字的原因,请查看http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#36930

当线程处于非运行(Run)状态

当线程处于下面的状况时,属于非运行状态:

  • 当sleep方法被调用。

  • 当wait方法被调用。

  • 当被I/O阻塞,可能是文件或者网络等等。

当线程处于上述的状态时,使用前面介绍的方法就不可用了。这个时候,我们可以使用interrupt()来打破阻塞的情况,如:

public void stop() {
        Thread tmpBlinker = blinker;
        blinker = null;
        if (tmpBlinker != null) {
           tmpBlinker.interrupt();
        }
    }

interrupt()被调用的时候,InterruptedException将被抛出,所以你可以再run方法中捕获这个异常,让线程安全退出:

try {
   ....
   wait();
} catch (InterruptedException iex) {
   throw new RuntimeException("Interrupted",iex);
}

阻塞的I/O

当线程被I/O阻塞的时候,调用interrupt()的情况是依赖与实际运行的平台的。在Solaris和Linux平台上将会抛出InterruptedIOException的异常,但是Windows上面不会有这种异常。所以,我们处理这种问题不能依靠于平台的实现。如:

package com.cnblogs.gpcuster

import java.net.*;
import java.io.*;

public abstract class InterruptibleReader extends Thread {

    private Object lock = new Object( );
    private InputStream is;
    private boolean done;
    private int buflen;
    protected void processData(byte[] b, int n) { }

    class ReaderClass extends Thread {

        public void run( ) {
            byte[] b = new byte[buflen];

            while (!done) {
                try {
                    int n = is.read(b, 0, buflen);
                    processData(b, n);
                } catch (IOException ioe) {
                    done = true;
                }
            }

            synchronized(lock) {
                lock.notify( );
            }
        }
    }

    public InterruptibleReader(InputStream is) {
        this(is, 512);
    }

    public InterruptibleReader(InputStream is, int len) {
        this.is = is;
        buflen = len;
    }

    public void run( ) {
        ReaderClass rc = new ReaderClass( );

        synchronized(lock) {
            rc.start( );
            while (!done) {
                try {
                    lock.wait( );
                } catch (InterruptedException ie) {
                    done = true;
                    rc.interrupt( );
                    try {
                        is.close( );
                    } catch (IOException ioe) {}
                }
            }
        }
    }
}

另外,我们也可以使用InterruptibleChannel接口。 实现了InterruptibleChannel接口的类可以在阻塞的时候抛出ClosedByInterruptException。如:

package com.cnblogs.gpcuster

import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.channels.Channels;

public class InterruptInput {   
    static BufferedReader in = new BufferedReader(
            new InputStreamReader(
            Channels.newInputStream(
            (new FileInputStream(FileDescriptor.in)).getChannel())));
    
    public static void main(String args[]) {
        try {
            System.out.println("Enter lines of input (user ctrl+Z Enter to terminate):");
            System.out.println("(Input thread will be interrupted in 10 sec.)");
            // interrupt input in 10 sec
            (new TimeOut()).start();
            String line = null;
            while ((line = in.readLine()) != null) {
                System.out.println("Read line:'"+line+"'");
            }
        } catch (Exception ex) {
            System.out.println(ex.toString()); // printStackTrace();
        }
    }
    
    public static class TimeOut extends Thread {
        int sleepTime = 10000;
        Thread threadToInterrupt = null;    
        public TimeOut() {
            // interrupt thread that creates this TimeOut.
            threadToInterrupt = Thread.currentThread();
            setDaemon(true);
        }
        
        public void run() {
            try {
                sleep(10000); // wait 10 sec
            } catch(InterruptedException ex) {/*ignore*/}
            threadToInterrupt.interrupt();
        }
    }
}

这里还需要注意一点,当线程处于写文件的状态时,调用interrupt()不会中断线程。

参考资料

How to Stop a Thread or a Task

Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?


不提倡的stop()方法 
臭名昭著的stop()停止线程的方法已不提倡使用了,原因是什么呢?
 当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会立即停止,并抛出特殊的ThreadDeath()异常。这里的“立即”因为太“立即”了,
假如一个线程正在执行:

synchronized void {
 x = 3;
 y = 4;
}

  由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x = 3;时,被调用了 stop()方法,即使在同步块中,它也干脆地stop了,这样就产生了不完整的残废数据。而多线程编程中最最基础的条件要保证数据的完整性,所以请忘记 线程的stop方法,以后我们再也不要说“停止线程”了。

   如何才能“结束”一个线程?

interupt()中断线程

一个线程从运行到真正的结束,应该有三个阶段:
  1. 正常运行.
  2. 处理结束前的工作,也就是准备结束.
  3. 结束退出.
那么如何让一个线程结束呢?既然不能调用stop,可用的只的interrupt()方法。但interrupt()方法只是改变了线程的运行状态,如何让它退出运行?对于一般逻辑,只要线程状态已经中断,我们就可以让它退出,这里我们定义一个线程类ThreadA,所以这样的语句可以保证线程在中断后就能结束运行:
 while(!isInterrupted()){
  正常逻辑
 }

,一个测试类,ThreadDemo
  这样ThreadDemo调用interrupt()方法,isInterrupted()为true,就会退出运行。但是如果线程正在执行wait,sleep,join方法,你调用interrupt()方法,这个逻辑就不完全了。
我们可以这样处理:
 public void run(){
  
  while(!isInterrupted()){
   try{
    正常工作
   }catch(InterruptedException e){
    //nothing
   }
  
  }
 } 
}
想一想,如果一个正在sleep的线程,在调用interrupt后,会如何?wait方法检查到isInterrupted()为true,抛出异常, 而你又没有处理。而一个抛出了InterruptedException的线程的状态马上就会被置为非中断状态,如果catch语句没有处理异常,则下一 次循环中isInterrupted()为false,线程会继续执行,可能你N次抛出异常,也无法让线程停止。
这个错误情况的实例代码
ThreadA

public  class ThreadA  extends Thread  {
   int count=0;
   public void run(){
       System.out.println(getName()+"将要运行...");
       while(!this.isInterrupted()){
           System.out.println(getName()+"运行中"+count++);
           try{
               Thread.sleep(400);
           }
catch(InterruptedException e){
               System.out.println(getName()+"从阻塞中退出...");
               System.out.println("this.isInterrupted()="+this.isInterrupted());

           }

       }

       System.out.println(getName()+"已经终止!");
   }

}

ThreadDemo
public  class ThreadDemo  {
    
    public static void main(String argv[])throws InterruptedException{
        ThreadA ta=new ThreadA();
        ta.setName("ThreadA");
        ta.start();
        Thread.sleep(2000);
        System.out.println(ta.getName()+"正在被中断...");
        ta.interrupt();
        System.out.println("ta.isInterrupted()="+ta.isInterrupted());
    }


}


 那么如何能确保线程真正停止?在线程同步的时候我们有一个叫“二次惰性检测”(double check),能在提高效率的基础上又确保线程真正中同步控制中。那么我把线程正确退出的方法称为“双重安全退出”,即不以isInterrupted ()为循环条件。而以一个标记作为循环条件:
正确的ThreadA代码是:
 

public  class ThreadA  extends Thread  {
    private boolean isInterrupted=false;
   int count=0;
   
   public void interrupt(){
       isInterrupted = true;
       super.interrupt();
      }

   
   public void run(){
       System.out.println(getName()+"将要运行...");
       while(!isInterrupted){
           System.out.println(getName()+"运行中"+count++);
           try{
               Thread.sleep(400);
           }
catch(InterruptedException e){
               System.out.println(getName()+"从阻塞中退出...");
               System.out.println("this.isInterrupted()="+this.isInterrupted());

           }

       }

       System.out.println(getName()+"已经终止!");
   }

}


    在java多线程编程中,线程的终止可以说是一个必然会遇到的操作。但是这样一个常见的操作其实并不是一个能够轻而易举实现的操作,而且在某些场景下情况会变得更复杂更棘手。

        Java标准API中的Thread类提供了stop方法可以终止线程,但是很遗憾,这种方法不建议使用,原因是这种方式终止线程中断临界区代码执行,并会释放线程之前获取的监控器锁,这样势必引起某些对象状态的不一致(因为临界区代码一般是原子的,不会被干扰的),具体原因可以参考资料[1]。这样一来,就必须根据线程的特点使用不同的替代方案以终止线程。根据停止线程时线程执行状态的不同有如下停止线程的方法。

1 处于运行状态的线程停止

        处于运行状态的线程就是常见的处于一个循环中不断执行业务流程的线程,这样的线程需要通过设置停止变量的方式,在每次循环开始处判断变量是否改变为停止,以达到停止线程的目的,比如如下代码框架:

[java]  view plain copy
  1. private volatile Thread blinker;  
  2. public void stop() {  
  3.         blinker = null;  
  4. }  
  5. public void run() {  
  6.         Thread thisThread = Thread.currentThread();  
  7.         while (blinker == thisThread) {  
  8.             try {  
  9.                 //业务流程  
  10.             } catch (Exception e){}  
  11.         }  
  12. }<span style="font-size:12px;">  
  13. </span>  

        如果主线程调用该线程对象的stop方法,blinker对象被设置为null,则线程的下次循环中blinker=thisThread,因而可以退出循环,并退出run方法而使线程结束。将引用变量blinker的类型前加上volatile关键字的目的是防止编译器对该变量存取时的优化,这种优化主要是缓存对变量的修改,这将使其他线程不会立刻看到修改后的blinker值,从而影响退出。此外,Java标准保证被volatile修饰的变量的读写都是原子的。

        上述的Thread类型的blinker完全可以由更为简单的boolean类型变量代替。

2 即将或正在处于非运行态的线程停止

        线程的非运行状态常见的有如下两种情况:

可中断等待:线程调用了sleepwait方法,这些方法可抛出InterruptedException

Io阻塞:线程调用了IOread操作或者socketaccept操作,处于阻塞状态。

2.1 处于可中断等待线程的停止

        如果线程调用了可中断等待方法,正处于等待状态,则可以通过调用Threadinterrupt方法让等待方法抛出InterruptedException异常,然后在循环外截获并处理异常,这样便跳出了线程run方法中的循环,以使线程顺利结束。

        上述的stop方法中需要做的修改就是在设置停止变量之后调用interrupt方法:

[java]  view plain copy
  1. private volatile Thread blinker;  
  2. public void stop() {  
  3.         Thread tmp = blinker;  
  4.         blinker = null;  
  5.         if(tmp!=null){  
  6.             tmp.interrupt();  
  7.         }  
  8. }  

         特别的,Thread对象的interrupt方法会设置线程的interruptedFlag,所以我们可以通过判断Thread对象的isInterrupted方法的返回值来判断是否应该继续run方法内的循环,从而代替线程中的volatile停止变量。这时的上述run方法的代码框架就变为如下:

[java]  view plain copy
  1. public void run() {  
  2.         while (!Thread.currentThread().isInterrupted()) {  
  3.             try {  
  4.                 //业务流程  
  5.             } catch (Exception e){}  
  6.         }  
  7. }  

        需要注意的是Thread对象的isInterrupted不会清除interrupted标记,但是Thread对象的interrupted方法(与interrupt方法区别)会清除该标记。

2.2 处于IO阻塞状态线程的停止

         Java中的输入输出流并没有类似于Interrupt的机制,但是JavaInterruptableChanel接口提供了这样的机制,任何实现了InterruptableChanel接口的类的IO阻塞都是可中断的,中断时抛出ClosedByInterruptedException,也是由Thread对象调用Interrupt方法完成中断调用。IO中断后将关闭通道。

        以文件IO为例,构造一个可中断的文件输入流的代码如下:

[java]  view plain copy
  1. new InputStreamReader(  
  2.            Channels.newInputStream(  
  3.                    (new FileInputStream(FileDescriptor.in)).getChannel())));   

         实现InterruptableChanel接口的类包括FileChannel,ServerSocketChannel, SocketChannel, Pipe.SinkChannel andPipe.SourceChannel,也就是说,原则上可以实现文件、Socket、管道的可中断IO阻塞操作。

        虽然解除IO阻塞的方法还可以直接调用IO对象的Close方法,这也会抛出IO异常。但是InterruptableChanel机制能够使处于IO阻塞的线程能够有一个和处于中断等待的线程一致的线程停止方案。

3 处于大数据IO读写中的线程停止

         处于大数据IO读写中的线程实际上处于运行状态,而不是等待或阻塞状态,因此上面的interrupt机制不适用。线程处于IO读写中可以看成是线程运行中的一种特例。停止这样的线程的办法是强行closeio输入输出流对象,使其抛出异常,进而使线程停止。

        最好的建议是将大数据的IO读写操作放在循环中进行,这样可以在每次循环中都有线程停止的时机,这也就将问题转化为如何停止正在运行中的线程的问题了。

4 在线程运行前停止线程

         有时,线程中的run方法需要足够健壮以支持在线程实际运行前终止线程的情况。即在Thread创建后,到Threadstart方法调用前这段时间,调用自定义的stop方法也要奏效。从上述的停止处于等待状态线程的代码示例中,stop方法并不能终止运行前的线程,因为在Threadstart方法被调用前,调用interrupt方法并不会将Thread对象的中断状态置位,这样当run方法执行时,currentThreadisInterrupted方法返回false,线程将继续执行下去。

         为了解决这个问题,不得不自己再额外创建一个volatile标志量,并将其加入run方法的最开头:

[java]  view plain copy
  1. public void run() {  
  2.         if (myThread == null) {  
  3.            return// stopped before started.  
  4.         }  
  5.         while(!Thread.currentThread().isInterrupted()){  
  6.     //业务逻辑  
  7.         }  
  8. }  

         还有一种解决方法,也可以在run中直接使用该自定义标志量,而不使用isInterrupted方法判断线程是否应该停止。这种方法的run代码框架实际上和停止运行时线程的一样。

5 参考资料

[1] Why Are Thread.stop, Thread.suspend, Thread.resume andRuntime.runFinalizersOnExit Deprecated?http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html.

[2] How to Stop a Thread or a Task.http://forward.com.au/javaProgramming/HowToStopAThread.html.

[3] JavaTM Platform Standard Edition 6 API.http://www.ostools.net/apidocs/apidoc?api=jdk-zh.

[4] Bruce Eckel. Thinking in Java, 4th Edition. Prentice Hall, 2006.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何终止java线程 的相关文章

随机推荐

  • c++中的类模板

    C 的类模板为生成通用的类声明提供了一种更好的方法 模板提供参数化类型 即能够将类型名作为参数传递给接收方来建立类或者函数 一 定义类模板 include
  • IndexError: index 5 is out of bounds for axis 1 with size 5

    keras中报错 IndexError index 5 is out of bounds for axis 1 with size 5 原因 大概率是你的数据集label没有设置好 keras中数据集标签需要从0开始 并且连续 类似于下图这
  • Unity WebGL错误集锦

    ips 0 Unity的PlayerSettings的otherSettings或者Publish Settings里面的Enable Exceptions里面选择Full StackTrace 可以在打出的包中的浏览器的webgl打印出错
  • 【计算机基础

    定点数的表示 定点数 小数点的位置固定 例 996 007 常规计数 浮点数 小数点的位置不固定 例 9 96007 10 2 科学计数法 二进制的定点数 浮点数也类似 无符号数 整个机器字长的全部二进制位均为数值位 没有符号位 相当于数的
  • 关于Linux和Shell的相关书籍

    入门类 一直认为 在一个系统上学习开发之前 首先需要熟悉这个系统的使用 鉴于天朝的国情 绝大部分人第一个接触的操作系统就是Windows 因此对于这绝大部分人来说 如果要学习Linux开发 学会使用这个系统都是必不可少的一个环节 现在的Li
  • UVa 1347 Tour

    题目 Tour 题意 来自luogu John Doe想用最小的路程游览完所有目的地 每个目的地都用坐标xi yi表示 任何两目的地的xi都不相同 两目的地之间的路程是两点之间的直线距离 John是这样走的 他从最左边的点开始 然后只能向右
  • word页码如何设置为章节加页码,例如第一章第一页1-1、第二章第一页2-1

    由于用到word页码分章节 页码的形式 从网上查了一下 质量真的很差 没有一篇文章讲清楚的 有的所答非所问 一怒之下 利用几个小时的时间解决问题并写下这篇文章 以供大家学习参考 1 word插入页码 选择包含章节号 1 1 双击页脚 点击插
  • 55黑马QT笔记之关闭子线程

    55黑马QT笔记之关闭子线程 1 这里为什么要单独写多一篇文章来说线程的关闭呢 主要是想让大家提升印象 养成资源回收的好习惯 任何时候都要想起开辟过的内存回收 这里的关闭子线程上一篇也写到了 就是利用关闭窗口时调用槽函数回收掉 2 具体步骤
  • 2023最新ChatGPT网站源码+支持GPT4+Ai绘画+用户会员套餐+邀请分佣功能+支持后台一键更新+永久更新!

    2023最新ChatGPT网站源码 支持GPT4 Ai绘画 用户会员套餐 邀请分佣功能 支持后台一键更新 永久更新 可同时 单独 开启或者关闭GPT3 5和GPT4 0两种ChatGPT提问模型 用户可切换 次数套餐也是分开的 支持手机电脑
  • News Feed 系统设计

    新鲜事系统 News Feed 什么是新鲜事 News Feed 你登陆 Facebook Twitter 朋友圈 之后看到的信息流 你的所有朋友发的信息的集合 有哪些典型的新鲜事系统 Facebook Twitter 朋友圈 RSS Re
  • Windows与Linux系统实现文件互传(通俗易懂)

    SCP指令可以实Windows系统与Linux系统之间的文件互传 引言 Windows系统文件传输到Linux系统上 先操作 Windows系统文件传输到Linux系统上 再细聊 Linux系统文件传输到Windows系统上 先操作 Lin
  • 趁着周日我卷了 uni-app《uview 狠 优秀的UI框架》

    前期回顾 手写一个服务器代码将 vue电商后台管理系统 部署上去 上线 打包 活在风浪里的博客 CSDN博客亲测可用 一定会收获颇多 1 上线vue电商后台管理项目2 手写搭建服务器并挂载 node 3 打包优化 完成上线https blo
  • Shell数组:shell数组的定义、数组长度

    Shell在编程方面比Windows批处理强大很多 无论是在循环 运算 bash支持一维数组 不支持多维数组 并且没有限定数组的大小 类似与C语言 数组元素的下标由0开始编号 获取数组中的元素要利用下标 下标可以是整数或算术表达式 其值应大
  • QGIS插件式开发(一)---PyQt5+python3.6+Pychram2017.3开发环境配置

    1 PyQt简介 PyQt是用来创建GUI应用程序的工具包 它把python和Qt成功地绑定在一起 Qt库是目前最强大的库之一 PyQt是由Phil Thompson开发 PyQt实现了一个Python模块集 它有超过300个类 将近600
  • 通过哲学家进餐问题学习线程间协作(代码实现以leetcode1226为例)

    哲学家进餐问题 代码实现以leetcode1226为例 问题场景 解决思路 解决死锁问题 代码实现 c go 代码实现以leetcode1226为例 提到多线程和锁解决问题 就想到了os中哲学家进餐问题 问题场景 回想该问题产生场景 五个哲
  • 流形学习(Manifold Learning)

    https www cnblogs com jiangxinyang p 9314256 html 1 什么是流形 流形学习的观点 认为我们所能观察到的数据实际上是由一个低维流行映射到高维空间的 由于数据内部特征的限制 一些高维中的数据会产
  • 数学(五) -- LC[415]&[455] 字符串相加与两数相加

    1 字符串相加 1 1 题目描述 给定两个字符串形式的非负整数 num1 和num2 计算它们的和并同样以字符串形式返回 你不能使用任何內建的用于处理大整数的库 比如 BigInteger 也不能直接将输入的字符串转换为整数形式 示例 1
  • qtdesigner界面美化

    文章目录 前言 一 QSS 1 1 QSS选择器介绍 2 2 使用 二 自定义属性 2 1 添加自定义属性 前言 pyqt5能快速构建界面 但是你会发现构建出来的界面没有像我们平常用的客户端界面一样美观 现在 就让我学习一下如何美化界面 本
  • 如何防止过拟合和欠拟合

    过拟合和欠拟合是模型训练过程中经常出现的问题 两种情况正好相反 现将两者的定义及如何防止进行简要总结 1 过拟合 1 1 定义 是指模型对于训练数据拟合呈现过当的情况 反映到评估指标上就是模型在训练集上的表现很好 但是在测试集上的表现较差
  • 如何终止java线程

    终止线程的三种方法 有三种方法可以使终止线程 1 使用退出标志 使线程正常退出 也就是当run方法完成后线程终止 2 使用stop方法强行终止线程 这个方法不推荐使用 因为stop和suspend resume一样 也可能发生不可预料的结果