《Head First Java》中银行账户示例:为何多个线程操作同一账户会导致Monica线程从中间开始执行?

《head first java》中银行账户示例:为何多个线程操作同一账户会导致monica线程从中间开始执行?

java并发编程问题

在《head first java》示例中,我们考察了bankaccount类的线程并发问题。

问题描述:

class bankaccount {
    private int balance = 100;

    public int getbalance() {
        return balance;
    }

    public void withdraw(int amount) {
        balance = balance - amount;
    }
}

public class ryanandmonicajob implements runnable {
    private bankaccount account = new bankaccount();

    public static void main(string[] args) {
        ryanandmonicajob thejob = new ryanandmonicajob();
        thread one = new thread(thejob);
        thread two = new thread(thejob);
        one.setname("ryan");
        two.setname("monica");
        one.start();
        two.start();
    }

    public void run() {
        for (int x = 0; x < 10; x++) {
            makewithdrawal(10);
            if (account.getbalance() < 0) {
                system.out.println("overdrawn!");
            }
        }
    }

    private void makewithdrawal(int amount) {
        string currentthread = thread.currentthread().getname();
        if (account.getbalance() >= amount) {
            system.out.println(currentthread + " is about to withdraw");
            try {
                system.out.println(currentthread + " is going to sleep");
                thread.sleep(500);
            } catch (interruptedexception ex) {
                ex.printstacktrace();
            }
            system.out.println(currentthread + " woke up.");
            account.withdraw(amount);
            system.out.println(currentthread + " completes the withdrawl");
        } else {
            system.out.println("sorry, not enough for " + currentthread);
        }
    }
}

该代码示例中,ryan和monica线程同时对同一个bankaccount对象进行操作。

示例输出:

Ryan is about to withdraw
Monica is about to withdraw
Ryan is going to sleep
Monica is going to sleep
Monica woke up.
Sorry, not enough for Monica
Ryan woke up.
Ryan completes the withdrawl
Monica is about to withdraw
...

问题:

代码中,ryan线程对makewithdrawal方法进行睡眠操作后,为什么monica线程会从makewithdrawal方法中间开始执行,而不是从头开始执行?

解答:

这是因为java中线程的调度是基于时间片的,当一个线程执行到一半时,计时器中断该线程,并将时间片交给其他线程执行。因此,monica线程能够在ryan线程睡眠时获得执行权,并从makewithdrawal方法中间的部分继续执行。

该示例展示了并发编程中的竞态条件,多个线程同时访问共享资源时可能导致意外结果。解决该问题的一种方法是使用同步机制,如锁或同步器,以确保对共享资源的访问是排他的。

以上就是《Head First Java》中银行账户示例:为何多个线程操作同一账户会导致Monica线程从中间开始执行?的详细内容,更多请关注其它相关文章!