作者:vbppn65853 | 来源:互联网 | 2023-02-04 20:44
我有一个简单的练习,我试图涉及线程.
(a)创建一个名为SumAction的类,它实现了Runnable.该类包含3个实例变量 - start,end和sum.start和end由构造函数初始化.sum设置为0.
(b)run()方法应该有一个for循环,它应该从开始到结束找到所有值的总和.应该有一个方法getSum()来返回sum的值.
(c)在main中创建此Runnable类的2个实例,一个以1和10为参数,另一个为10和20.
(d)将这些实例传递给2个线程构造函数以生成线程t1和t2.
(e)线程完成后,调用getSum从两个线程中获取总和值以查找总计.
我很确定我做得对,但我仍然得到0的总和值.
这是我的课
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
这是主要的
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());
Nathan Hughe..
8
你不是在等待线程完成.你的主线程可以在其他线程完成计算之前或甚至在它们开始之前调用getSum.此外,即使线程确实在println之前完成,主线程也可能看不到更新的值.
调用线程上的连接以等待它们完成,在启动线程之后和printlns之前添加它:
t1.join();
t2.join();
这样可以确保主线程在尝试打印总和之前等待其他线程完成,并且还会处理可见性问题.
在许多情况下,如果没有采取足够的预防措施(同步,使字段不稳定等),从另一个线程写入的字段中读取线程是有问题的(错误,依赖于实现,或者只是令人困惑且难以推理) .但是在这段代码中,如果你调用join,那么主线程不需要额外的同步来确保看到getSum的最新值,因为有一个适用的before-before规则.引用Oracle教程:
当一个线程终止并导致另一个线程中的Thread.join返回时,终止线程执行的所有语句与成功连接后的所有语句都有一个before-before关系.现在,执行连接的线程可以看到线程中代码的效果.
join方法抛出InterruptedException,如果线程在设置了中断标志后进入休眠或等待状态,则抛出一个已检查的异常.对于一个简单的示例程序,您实际上没有中断任何内容,可以将其添加到main方法的throws子句中.
1> Nathan Hughe..:
你不是在等待线程完成.你的主线程可以在其他线程完成计算之前或甚至在它们开始之前调用getSum.此外,即使线程确实在println之前完成,主线程也可能看不到更新的值.
调用线程上的连接以等待它们完成,在启动线程之后和printlns之前添加它:
t1.join();
t2.join();
这样可以确保主线程在尝试打印总和之前等待其他线程完成,并且还会处理可见性问题.
在许多情况下,如果没有采取足够的预防措施(同步,使字段不稳定等),从另一个线程写入的字段中读取线程是有问题的(错误,依赖于实现,或者只是令人困惑且难以推理) .但是在这段代码中,如果你调用join,那么主线程不需要额外的同步来确保看到getSum的最新值,因为有一个适用的before-before规则.引用Oracle教程:
当一个线程终止并导致另一个线程中的Thread.join返回时,终止线程执行的所有语句与成功连接后的所有语句都有一个before-before关系.现在,执行连接的线程可以看到线程中代码的效果.
join方法抛出InterruptedException,如果线程在设置了中断标志后进入休眠或等待状态,则抛出一个已检查的异常.对于一个简单的示例程序,您实际上没有中断任何内容,可以将其添加到main方法的throws子句中.