java 线程和 public void run()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15036325/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:18:26  来源:igfitidea点击:

Threads and public void run()

javamultithreading

提问by Tom Pengelly

import java.lang.Thread;

class ThreadExperiment implements Runnable {
  public static void main(String[] args) {
    Thread t = new Thread(new ThreadExperiment());
    @Override
    public void run(){      
        do {
            num ++;
            try {
                Thread.sleep(400);
            } catch (InterruptedException e){
            }
        } while (num >= 0);
    }

    Thread t2 = new Thread(new ThreadExperiment());
    @Override
    public void run() {
        do {
            num2--;
            try {
                Thread.sleep(400);
            } catch (InterruptedException e){
            }
        } while (num >= 1);
    }


    int num = 1;
    int num2 = 10;
    t.start();
    t2.start();
    if (num == num2) {
        t.interrupt();
        t2.interrupt();
    }
  }
}

Trying to tinker with threads and going round in circles, always getting so close. I want two threads, one increasing a number count, the other decreasing a number count. If they meet, I want them to stop. However I am having trouble with public void run() - at the moment, it says I dont have a semi-colon next to both of them. What isnt right? Is this the right place to put public void run()?

试图修补线程并绕圈子,总是如此接近。我想要两个线程,一个增加数量,另一个减少数量。如果他们见面,我希望他们停下来。但是,我在使用 public void run() 时遇到了麻烦 - 目前,它说我t have a semi-colon next to both of them. What isn不对?这是放置 public void run() 的正确位置吗?

Also, some websites are saying I need two separate classes forcreating threads - is there a reason for this? Maybe if one threads relies on calculations from the other but goes a different route, I can understand, but mine feels different, just two separate entities.

另外,一些网站说我需要两个单独的类来创建线程 - 这有什么原因吗?也许如果一个线程依赖于另一个线程的计算但走不同的路线,我可以理解,但我的感觉不同,只是两个独立的实体。

Lastly, do I need the import statement?

最后,我需要导入语句吗?

回答by Hovercraft Full Of Eels

First of all, your code looks like it should have lots of compilation errors which suggests to me that may be going about coding the wrong way. If you can't use an IDE, then you mustcompile early and often and not any any more new code until allcompilation errors have been fixed.

首先,您的代码看起来应该有很多编译错误,这向我表明可能会以错误的方式进行编码。如果您不能使用 IDE,那么您必须尽早且经常编译,并且在修复所有编译错误之前不要再添加任何新代码。

For instance, you appear to have a method, run, embedded within another method, main, and you simply cannot do this. I suggest that you start over, beginning with a small code skeleton that compiles, and then again compile early and often. Also get most of your code outsideof your main method. And no, the run method is not in the correct location as you should only have onerun method and it should be in the class itself, not embedded within the main or any other method.

例如,您似乎有一个方法 run,嵌入在另一个方法 main 中,而您根本无法做到这一点。我建议您重新开始,从一个可以编译的小代码框架开始,然后再次尽早并经常编译。还可以在 main 方法之外获取大部分代码。不,run 方法不在正确的位置,因为您应该只有一个run 方法,并且它应该在类本身中,而不是嵌入在 main 或任何其他方法中。

Regarding,

关于,

Lastly, do I need the import statement?

最后,我需要导入语句吗?

Your compiler will tell you this: Get rid of the import and see what happens.

你的编译器会告诉你:去掉导入,看看会发生什么。

回答by Capn Sparrow

1). You want your code to compile.

1)。您希望您的代码能够编译。

Your compilation problems are because you're to declare your run methods within the main method. Separate you method declarations and then just use main to create & run your threads.

你的编译问题是因为你要在 main 方法中声明你的 run 方法。将你的方法声明分开,然后只使用 main 来创建和运行你的线程。

2). You want to have two threads operating concurrently.

2)。您希望有两个线程同时运行。

This means we need to either define two different thread classes or a single thread with logic to handle both incrementing and decrementing. Andrew Mao's answer gives you a start on how you might define two separate threads. My code above uses a single definition for a run method that uses a parameter to work out which way to go.

这意味着我们需要定义两个不同的线程类或一个具有处理递增和递减逻辑的线程。Andrew Mao 的回答让您开始了解如何定义两个单独的线程。我上面的代码对 run 方法使用单个定义,该方法使用参数来确定要走的路。

3). You want to have two threads operating concurrently on the same data, because while they're incrementing/decrementing separately, they need to check for collisions.

3)。您希望两个线程同时操作同一数据,因为当它们分别递增/递减时,它们需要检查冲突。

An easy way to do this is to create the objects you want to work on (num1 and num2) in your main method and then just pass references to these objects to your threads. Example in my code above.

一个简单的方法是在你的主方法中创建你想要处理的对象(num1 和 num2),然后将这些对象的引用传递给你的线程。我上面代码中的示例。

4). You want to test things

4)。你想测试的东西

All of java.lang.* is kind of assumed to be imported automatically. No harm in putting it there for clarity but auto-importer commands on your dev tool of choice will probably remove it as redundant.

所有 java.lang.* 都假定为自动导入。为了清楚起见,将它放在那里没有坏处,但是您选择的开发工具上的自动导入器命令可能会将其删除为多余的。

public class ThreadExperiment implements Runnable {
    /* these fields are unique to each instance of ThreadExperiment */
    private int increment = 0;

    /* these are used to point to the original num1 and num2 instances created in your main method */ 
    private Integer myNumber;
    private Integer theOtherNumber;


/** 
 * Constructor.   
 */
public ThreadExperiment(int increment, Integer num1Ref, Integer num2Ref) {
    this.increment = increment;
    this.myNumber = num1Ref;
    this.theOtherNumber = num2Ref;
}


@Override
public void run() {
    do {
        myNumber += increment;
        try {
            Thread.sleep(400);
        } catch (InterruptedException e) {
        }
        System.out.println(Thread.currentThread().getName() + " -- " + myNumber);
    } while (!myNumber.equals(theOtherNumber));
}


/** 
 * Your static main method used to instantiate & start threads 
 */
public static void main(String[] args) {
    Integer num1 = 0;
    Integer num2 = 10;

    Thread t = new Thread(new ThreadExperiment(1, num1, num2), "Thread 1");
    Thread t2 = new Thread(new ThreadExperiment(-1, num2, num1), "Thread 2");
    t.start();
    t2.start();
}

}

回答by Andrew Mao

The runmethod that is implemented by a thread needs to be in a separate class. You can certainly put one of them in your ThreadExperimentclass, but it can't be both. In this case, you can separate the two threads into inner classes:

run线程实现的方法需要在一个单独的类中。您当然可以将其中一个放在您的ThreadExperiment班级中,但不能同时使用。在这种情况下,您可以将两个线程分成内部类:

class ThreadExperiment {

  static int num = 1;
  static int num2 = 10;

  class Thread1 implements Runnable {
    @Override
    public void run(){      
        do {
            num++;
            try {
                Thread.sleep(400);
            } catch (InterruptedException e){
            }
        } while (num >= 0);
    }
  }

  class Thread2 implements Runnable {
    @Override
    public void run() {
        do {
            num2--;
            try {
                Thread.sleep(400);
            } catch (InterruptedException e){
            }
        } while (num >= 1);
    }
  }

  public static void main(String[] args) {

    Thread t = new Thread(new Thread1());    
    Thread t2 = new Thread(new Thread2());    

    t.start();
    t2.start();

    if (num == num2) {
        t.interrupt();
        t2.interrupt();
    }
  }
}

Now we're getting somewhere, but you still need to fix some issues with your logic:

现在我们到达了某个地方,但您仍然需要解决一些逻辑问题:

  • Having the ints as static isn't good practice. (But it's okay for this testing scenario.)
  • Your num == num2check will happen only once and there are no guarantees on what the values will be there when that happens. It is very unlikely that the threads will be interrupted.
  • You need to declare the ints volatilesince they will be read by different threads.
  • The whilecondition in Thread1will result in an infinite loop.
  • ints 设为静态并不是一个好习惯。(但对于这个测试场景来说是可以的。)
  • 您的num == num2检查只会发生一次,并且无法保证发生这种情况时会出现什么值。线程被中断的可能性很小。
  • 您需要声明ints,volatile因为它们将被不同的线程读取。
  • while状况Thread1将导致一个无限循环。