登录
首页 >  文章 >  java教程

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

时间:2024-11-25 19:36:55 488浏览 收藏

来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习文章相关编程知识。下面本篇文章就来带大家聊聊《《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线程从中间开始执行?》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!

相关阅读
更多>
最新阅读
更多>
课程推荐
更多>