0

在下面的代码中,在线程运行increment方法后,它将值2输出到控制台。不应该将值设为1,因为方法用1递增?为什么下面的代码增加2而不是1?(Java新手)

class TestSync implements Runnable { 
private int balance; 

public void run() { 

    for(int i = 0; i < 50; i++){ 

     increment(); 
     System.out.println(Thread.currentThread().getName() + " balance after increment is " +balance); 
    } 

} 

private synchronized void increment() { 

    int i = balance; 
    balance = i + 1; 
    // System.out.println(balance); 
} 

}

公共类TestSyncTest {

public static void main(String[] args) { 

    TestSync job = new TestSync(); 
    Thread a = new Thread(job); 
    Thread b = new Thread(job); 
    a.setName("Thread A"); 
    b.setName("Thread B"); 

    a.start(); 
    b.start(); 

} 

}

+1

如果两个线程递增值之前,任何人获得打印出的价值是什么? – tkausl

+0

尝试评论现有的'System.out.println'并取消注释,现在你已经注释掉了。 –

+0

你能检查我的答案吗? – KeLiuyue

回答

0

因为你的代码是在循环中。而balance是全球性的数据。

在第一个循环中,您的balance的值为1

for (int i = 0; i < 50; i++) { 

     increment(); 
     System.out.println(Thread.currentThread().getName() + " balance after increment is " + balance); 
} 

OUTPUT

//   i  balance 
// first 0   1 
// second 1   2 
// third 2   3 
// ... 
+0

我明白你想要解释的逻辑。print语句输出的是从2开始而不是1开始的值,这就是让我困惑的原因。 –

+0

你可以调试它,让你更容易理解 – KeLiuyue

0

你的增量方法是同步的,但平衡变量由线程共享。在第一个线程调用增量之后,在可以打印余额之前,另一个线程可以调用增量。将print语句放在increment方法中。

0

两个线程共享同一个对象。唯一的同步方法会增加i的值,但不能保证在打印该值时它们将不会为打印它的状态而执行的顺序。

如果您希望每种方法都在增量后打印其值,请从同步方法中取消注释sysout并将其从run()中删除。

如果您希望在打印之前完成所有线程,则需要使用Thread.join()

这里有一个简单的例子:

class TestSync implements Runnable { 
    private int balance; 

    public void run() { 

     for(int i = 0; i < 50; i++){ 
      increment(); 
     } 

    } 

    private synchronized void increment() { 

     int i = balance; 
     balance = i + 1; 
    } 

    public void printBalance() ´{ 
     System.out.println("Balance: " + balance); 
    } 
} 

public static void main(String[] args) { 

    TestSync job = new TestSync(); 
    Thread a = new Thread(job); 
    Thread b = new Thread(job); 
    a.setName("Thread A"); 
    b.setName("Thread B"); 

    a.start(); 
    b.start(); 

    try { 
     System.out.println("Wait for threads to finish."); 
     a.join(); 
     b.join(); 
    } catch (InterruptedException e) { 
     System.out.println("Interruption waiting for threads to finish."); 
    } 
    a.printBalance(); // either method will print the same value. 
} 
相关问题