使用synchronized关键字和join()的输出差异

时间:2013-11-07 09:45:58

标签: java multithreading join synchronized

我有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方法中添加synchronized关键字

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

这表明只有Thread t1正在运行......

如果我取消评论该行

t1.join();

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

如果我不使用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()有何不同? 我们是否需要将synchronized关键字添加到run()?

2 个答案:

答案 0 :(得分:1)

  

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

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

我建议您查阅每个文档:

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

完成这项工作,它将清除你的很多问题。

  

那么来自synchronized的输出与join()有什么不同?

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

答案 1 :(得分:1)

synchronized将不允许其他线程同时访问同一资源。

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