• 线程的同步


    线程的同步:

      由于同一进程的多个线程共享存储空间,在带来方便的同时也带来访问冲突的问题。例如在本例中若两个线程同时访问变量balance,会造成结果不符合实际要求的情况,在本例中描述为:一个账号余额为1000元,两个或多个线程同时进行取款1000元操作,但取款操作后结果出现余额为负数,这与实际情况余额应该大于0元的结果不符。

      在java中引入了“对象互斥锁”的概念来实现对不同线程的共享数据操作的同步。“对象互斥锁”不允许多个线程同时访问同一个条件变量(即共享数据)。实质上,是把多个线程对象并行的访问数据共享改为串行的访问数据,即同一时刻最多只有一个对象访问共享数据。

      java中针对方法提出一套机制,就是synchronized关键字,它包括两种用法:synchronized修饰方法和synchronized修饰程序块。

    本例中定义了3个类:
    Bank(定义银行账号),Operation(线程类,实现存/取款操作)和TestBankOperation(主类)
    本例中实现线程同步的方法:
    1)给public void deposite(double dmount)和 public void withdrawal(double dmount)方法加锁,
    即加上关键字 synchronized
    2)在取款和存款的过程中给bank对象加锁

    public class TestBankOperation {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Bank bank = new Bank("1002",1000);
            //创建线程的方法一:继承Thread类
            new Operation(1+"# ",bank,1000).start();
            new Operation(0+"# ",bank,1000).start();
            new Operation(3+"# ",bank,1000).start();
            /*
            //创建线程的方法二:实现Runnable接口
            Operation o = new Operation("#",bank,1000);
            Thread t1 = new Thread(o);
            Thread t2 = new Thread(o);
            Thread t3 = new Thread(o);
            t1.start();
            t2.start();
            t3.start();
            */
        }
    }
    
    /*
     *线程类,实现了同步取款操作
     */
    class Operation extends Thread
    //class Operation implements Runnable
    {
        Bank bank;
        double mount;
        String name;
        public Operation(String name)
        {
            super(name);
            //this.name = name;
        }
        public Operation(String name,Bank bank,double dmount)
        {
            super(name);
            //this.name = name;
            this.bank = bank;
            this.mount = dmount;
        }
        /*
        public void run()
        {
            //bank.deposite(mount);
            bank.withdrawal(mount);
        }
        */
        public void run()
        {
            synchronized(bank)
            {
                bank.withdrawal(mount);
            }    
        }
    }
    /*
     * 银行账号类
     */
    class Bank
    {
        
        String account;//账号
        double balance;//余额
        Bank(String account,double balance)
        {
            this.setAccount(account);
            this.balance = balance;
        }
        //设置账号
        public void setAccount(String account)
        {
            this.account = account;
        }
        //设置余额
        public void setBalance(double balance)
        {
            this.balance = balance;
        }
        //获取账号
        public String getAccount()
        {
            return this.account;
        }
        //获取余额
        public double getBanlance()
        {
            return this.balance;
        }
        /*
         * 存款
         * @param dmount存款金额
         */
        public void deposite(double dmount)
        //public synchronized void deposite(double dmount)
        {
            this.setBalance(this.getBanlance()+dmount);
            System.out.println(Thread.currentThread().getName()+"线程存款成功!  "+"存款为:" + dmount + "   当前余额为:" + this.balance+"
    ");
        }
        
        /*
         * 取款操作
         * @param dmount 取款金额
         */
        public void withdrawal(double dmount)
        //public synchronized void withdrawal(double dmount)
        {
            if(dmount <= this.balance)
            {
                System.out.println(Thread.currentThread().getName()+"线程取款成功!  "+"吐出钞票为:" + dmount);
                this.setBalance(this.balance-dmount);
                System.out.println("当前余额为:" + this.balance+"
    ");
            }
            else
                System.out.println("余额不足!");
        }
            
    }

    某次运行结果:

  • 相关阅读:
    Java——HTTPServletRequest的使用
    JavaWeb——HttpServletResponse的使用,文件下载
    JavaWeb——Servlet简介
    JavaWeb——TomCat服务器
    HTTP与HTTPS
    Java——DBCP连接池
    Java——JDBC连接MySQL
    Java——线程锁,死锁,等待唤醒机制
    LeetCode118. 杨辉三角
    LeetCode66. 加一
  • 原文地址:https://www.cnblogs.com/UUUP/p/3811755.html
Copyright © 2020-2023  润新知