简体   繁体   English

我是在产生线程并导致 memory 泄漏吗?

[英]am I spawning threads and causing a memory leak?

I am converting a C++ program to Java for same implementation as a learning exercise and this java has a lot of things I am not yet familiar with, I had a long break in my work in the field.我正在将 C++ 程序转换为 Java 以实现与学习练习相同的实现,而这个 java 有很多我不熟悉的工作,我在这个领域有很多休息时间。

Well here is the code:那么这里是代码:

public class MythicQuestDriver {
    
    public static void clrscr(){

        //Clears Screen in java

        try {

            if (System.getProperty("os.name").contains("Windows"))

                new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();

            else

                Runtime.getRuntime().exec("clear");

        } catch (IOException | InterruptedException ex) {}

    }
    

    public static void main(String[] args) {
    
    int x = 0;  
        
    MythicClock ElflordsTimepiece = new MythicClock(7,7,7);
    
    ElflordsTimepiece.printMythicClockDetails();
    
    do {
    new MainGameThread();
    clrscr();
    

    }while(x != '5');
}}

the clear screen function is from https://intellipaat.com/community/294/java-clear-the-console清屏 function 来自https://intellipaat.com/community/294/java-clear-the-console

and here is the thread class I slightly modified:这是我稍微修改的线程 class :

package MythicQuestGame;

import java.lang.*;

public class MainGameThread implements Runnable{
    
    Thread t;

    MainGameThread() {

          t = new Thread(this);
          System.out.println("Executing " + t.getName());
       
          // this will call run() fucntion
          t.start();
            
          /* interrupt the threads
          if (!t.interrupted()) {
             t.interrupt();
          }*/
          
          // block until other threads finish
          try {  
             t.join();
          } catch(InterruptedException e) {}
       }
    
    
    @Override
    public void run() {
        
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("thread ran");
        
        // TODO Auto-generated method stub
        
    }

}

and when I run I get a second like tiker but it goes thread1 thread2 thread3... I know I am running an infinte loop and that is by design as I am working towards an interupt like getch in c++ from: Last Question当我运行时,我得到第二个像 tiker 但它进入 thread1 thread2 thread3 ... 我知道我正在运行一个无限循环,这是设计使然,因为我正在努力实现 c++ 中的中断,如: Last Question

So I have not got to the interupt thread join stuff yet, but am trying to follow the intent of what happens in my C++ code.所以我还没有得到中断线程连接的东西,但我试图遵循我的 C++ 代码中发生的事情的意图。 I am interested to know if I need a destructor method or does the way threads work does it get its memory footprint removed after it runs because if I run a thread a second or 3 times a second or more it is gonna generate so many threads, but it would not matter if they are all destroyed after they run?我很想知道我是否需要一个析构函数方法或线程的工作方式是否在运行后删除了它的 memory 足迹,因为如果我每秒运行一个线程或每秒运行 3 次或更长时间,它会生成这么多线程,但是跑完就全灭了也无所谓?

in my c++ program the implementation runs like this:在我的 c++ 程序中,实现运行如下:

int main() {
    std::atomic<bool> interrupted;
    char x;

  do {
        interrupted.store(false);

        // create a new thread that does stuff in the background

        std::thread timerThread([&]()
            {

                while (!interrupted)
                {

            // does game stuff moves monsters 
            // checks for random encounters every aprox 15 sec
            // runs a clearscreen every 15 seconds and refresh output
            // hosts enemy attacks if in encounter
            // updates clock timer one sec every 3  passes
            // runs every .3 seconds

            }});
            x = _getch();
        //take input without waiting for an enterkey pressed
       // upon input interrupt thread 


        interrupted.store(true);
        timerThread.join();

    // here the program does things like:
    //based on input does character actions like move or attack
    // takes almost second sleep and adds one second to clock timer
    // runs a clear screen and new output

    

    } while (x != '5'); // exit condition
}

If I correctly understand, you're trying to achieve a temporized screen clearing, right?如果我理解正确,您正在尝试实现临时屏幕清除,对吗?

In Java there's no such thing as destructors , specially when talking about threads where scheduling and thread's memory is mainly handled by the JVM itself (unless you're using shared objects like monitors ), so I think the problem in your code is how you're spawning threads. In Java there's no such thing as destructors , specially when talking about threads where scheduling and thread's memory is mainly handled by the JVM itself (unless you're using shared objects like monitors ), so I think the problem in your code is how you'重新产生线程。 You should try to do that this way:您应该尝试这样做:

MainGameThread constructor

MainGameThread(){
    System.out.println("Executing " + t.getName());
}

MythicQuestDriver.java

...
// Creates the Runnable just once
MainGameThread runnable = new MainGameThread();
do {
    // Use the same Runnable for each thread you want to spawn
    Thread t = new Thread(runnable);

    // Start the thread and immediately stop and wait for its conclusion
    t.start();
    t.join();

    // Clear the screen
    clrscr();
} while (x != 5)

With that said, I do not think you should spawn threads in a loop at all, unless you know exactly how many threads will spawn.话虽如此,我认为您根本不应该在循环中生成线程,除非您确切知道将生成多少线程。

Moreover, by starting a thread and then immediately stopping in order to wait for its conclusion you're really doing something that makes threads useless: in other words, you should reconsider your game's logic and adapt it to the way Java works, and not viceversa.此外,通过启动一个线程然后立即停止以等待其结束,您确实在做一些使线程无用的事情:换句话说,您应该重新考虑您的游戏逻辑并使其适应 Java 的工作方式,反之亦然. For a simple example like the one you asked, a thread is not even necessary, you should place your game's logic inside the main loop and clear the screen once its execution ends, eventually using threads for complementary jobs!对于像您问的那样的简单示例,甚至不需要线程,您应该将游戏的逻辑放在主循环中,并在其执行结束后清除屏幕,最终使用线程来完成补充工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM