java线程启动不工作 [英] java thread start not working

查看:126
本文介绍了java线程启动不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试做一个涉及线程的简单练习.

I have a simple exercise I am trying to do involving threads.

(a) 创建一个名为 SumAction 的类,它实现了 Runnable.该类包含 3 个实例变量——start、end 和 sum.start 和 end 由构造函数初始化.sum 设置为 0.

(a) Create a class called SumAction that implements Runnable. The class contains 3 instance variables – start, end, and sum. start and end are initialized by the constructor. sum is set to 0.

(b) run() 方法应该有一个 for 循环,它应该找到从开始到结束的所有值的总和.应该有一个方法 getSum() 来返回 sum 的值.

(b) The run() method should have a for loop which should find the sum of all values from start to end. There should be a method getSum() to return the value of sum.

(c) 在 main 创建这个 Runnable 类的 2 个实例,一个以 1 和 10 作为参数,另一个以 10 和 20 为参数.

(c) In main create 2 instances of this Runnable class, one which takes 1 and 10 as parameters, the other takes 10 and 20.

(d) 将这些实例传递给 2 个线程构造函数以创建线程 t1 和 t2.

(d) Pass these instances to 2 thread constructors to make threads t1 and t2.

(e) 当线程完成后,调用 getSum 获取两个线程的总和值以求总和.

(e) When the threads have finished, call getSum to get the sum value from both threads to find the overall total.

我很确定我这样做是正确的,但我仍然得到了 0 的总和值.

I am pretty sure I am doing this right but I am still getting the sum value of 0 back.

这是我的课

public class SumAction implements Runnable {

private int start, end, sum;

public SumAction(int start, int end) {
    this.start = start;
    this.end = end;
    sum = 0;
}

@Override
public void run()
{

    for (int i = start+1; i < end; i++)
    {
      sum += i;  
    }

}

public int getSum() {
    return sum;
}
}

这里是主要的

    SumAction run1 = new SumAction(1, 10);

    SumAction run2 = new SumAction(10, 20);

    Thread t1= new Thread(run1);

    Thread t2= new Thread(run2);


    t1.start();

    t2.start();


    System.out.println("Sum 1 : " + run1.getSum());

    System.out.println("Sum 2 : " + run2.getSum());

推荐答案

您不是在等待线程完成.您的主线程可以在其他线程完成计算之前或在它们开始之前调用 getSum.此外,即使线程碰巧在 println 之前完成,主线程也可能看不到更新的值.

You're not waiting for the threads to finish. Your main thread can call getSum before the other threads are done calculating or before they have even started. Also it's possible the updated values may not be visible to the main thread even if the thread does happen to finish before the println.

在线程上调用 join 以等待它们完成,在启动线程之后和 printlns 之前添加:

Call join on the threads to wait til they have finished, add this after starting the threads and before the printlns:

t1.join();
t2.join();

这可确保主线程在尝试打印总和之前等待其他线程完成,并处理可见性问题.

This makes sure the main thread waits until the other threads finish before trying to print the sums, and also takes care of the visibility issue.

在许多情况下,如果采取足够的预防措施(同步、使字段易变等),让一个线程从另一个线程写入的字段读取是有问题的(有问题、依赖于实现,或者只是令人困惑和难以推理)不被采取.但是在这段代码中,如果你调用 join ,那么主线程不需要额外的同步来确保看到 getSum 的最新值,因为有一个适用的happens-before 规则.引用 Oracle 教程:

In many cases having a thread read from a field written to by another thread is problematic (buggy, implementation-dependent, or just confusing and hard to reason about) if adequate precautions (synchronization, making the field volatile, etc.) are not taken. But in this code if you call join then no additional synchronization is required for the main thread to be assured to see the latest value of getSum, because there is an applicable happens-before rule. Quoting from the Oracle tutorial:

当一个线程终止并导致另一个线程中的 Thread.join 返回时,则被终止线程执行的所有语句与成功加入之后的所有语句都具有发生在之前的关系.线程中代码的效果现在对执行连接的线程可见.

When a thread terminates and causes a Thread.join in another thread to return, then all the statements executed by the terminated thread have a happens-before relationship with all the statements following the successful join. The effects of the code in the thread are now visible to the thread that performed the join.

join 方法抛出 InterruptedException,这是一个检查异常,如果线程在设置中断标志后进入睡眠或等待状态.对于一个简单的示例程序,您实际上并未中断任何内容,您可以将其添加到 main 方法的 throws 子句中.

The join method throws InterruptedException, which is a checked exception thrown if the thread enters a sleep or wait state after having its interrupt flag set. For a simple example program where you're not actually interrupting anything you can add it to the throws clause of the main method.

这篇关于java线程启动不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆