【问题标题】:Difference in output from use of synchronized keyword and join()使用 synchronized 关键字和 join() 的输出差异
【发布时间】:2013-11-07 09:45:57
【问题描述】:

我有 2 节课,

public class Account {
private int balance = 50;

public int getBalance() {
    return balance;
}
public void withdraw(int amt){
    this.balance -= amt; } }

public class DangerousAccount implements Runnable{
private Account acct = new Account();   

public static void main(String[] args) throws InterruptedException{
    DangerousAccount target = new DangerousAccount();
    Thread t1 = new Thread(target);
    Thread t2 = new Thread(target);

    t1.setName("Ravi");
    t2.setName("Prakash");
    t1.start();
/* #1 t1.join(); */
    t2.start();
}

public void run(){
    for(int i=0; i<5; i++){
        makeWithdrawl(10);
        if(acct.getBalance() < 0)
            System.out.println("Account Overdrawn");
    }
}
  public void makeWithdrawl(int amt){
        if(acct.getBalance() >= amt){
            System.out.println(Thread.currentThread().getName() + " is going to withdraw");
            try{
                Thread.sleep(500);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            acct.withdraw(amt);
      System.out.println(Thread.currentThread().getName() + " has finished the withdrawl");
    }else{
        System.out.println("Not Enough Money For " + Thread.currentThread().getName() + " to withdraw");
}
  }
}

我尝试在 makeWithdrawl 方法中添加同步关键字

public synchronized void makeWithdrawl(int amt){

而且我尝试多次都得到这个输出

Ravi is going to withdraw
Ravi has finished the withdrawl
Ravi is going to withdraw
Ravi has finished the withdrawl
Ravi is going to withdraw
Ravi has finished the withdrawl
Ravi is going to withdraw
Ravi has finished the withdrawl
Ravi is going to withdraw
Ravi has finished the withdrawl
Not Enough Money For Prakash to withdraw
Not Enough Money For Prakash to withdraw
Not Enough Money For Prakash to withdraw
Not Enough Money For Prakash to withdraw
Not Enough Money For Prakash to withdraw

这表明只有线程 t1 在工作...

如果我取消注释这行说

t1.join();

并从 makeWithdrawl 方法中删除同步关键字,我得到相同的输出。

如果我不使用 synchronize 关键字或 join() 我会得到各种输出,例如

Ravi is going to withdraw
Prakash is going to withdraw
Prakash has finished the withdrawl
Ravi has finished the withdrawl
Prakash is going to withdraw
Ravi is going to withdraw
Prakash has finished the withdrawl
Ravi has finished the withdrawl
Prakash is going to withdraw
Ravi is going to withdraw
Prakash has finished the withdrawl
Ravi has finished the withdrawl
Account Overdrawn
Account Overdrawn
Not Enough Money For Ravi to withdraw
Account Overdrawn
Not Enough Money For Prakash to withdraw
Account Overdrawn
Not Enough Money For Ravi to withdraw
Account Overdrawn
Not Enough Money For Prakash to withdraw
Account Overdrawn

那么 synchronized 的输出与 join() 有何不同? 我们是否需要在 run() 中添加 synchronized 关键字?

【问题讨论】:

    标签: java multithreading join synchronized


    【解决方案1】:

    同步不会允许其他线程同时访问相同的资源。

    synchronized method(){
          allowed one Thread at a time.
    }
    

    join 将等待子线程完成执行。

    Parent Thread started.
    
           Child Thread started
    
    Parent Thread is Completed but waiting for Child Thread to complete .
          Child Thread Completed 
    Parent Thread Completed 
    

    【讨论】:

      【解决方案2】:

      那么 synchronized 与 join() 有何不同?

      他们做完全不同的事情。 synchronized 用于防止两个线程同时执行同步的代码区域-在您的特定情况下,它会阻止两个线程同时运行makeWithdrawl()(如果它们同时到达那里,一个将等待另一个时间)。 Thread.join() 等待线程退出 - 在您的特定情况下,这将等待 t1 在启动 t2 之前完全完成。它们是苹果和橙子。

      我建议查阅每个文档:

      这里还有一个很好的官方并发教程:

      解决这个问题,它会解决你的很多问题。

      那么 synchronized 的输出与 join() 有何不同?

      您似乎已经在帖子中回答了这个问题;您可以清楚地看到输出的差异。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-08
        • 1970-01-01
        • 2021-05-16
        • 1970-01-01
        • 2019-08-14
        • 1970-01-01
        • 2018-05-02
        相关资源
        最近更新 更多