首页 > 代码库 > 线程的同步

线程的同步

线程的同步:

  由于同一进程的多个线程共享存储空间,在带来方便的同时也带来访问冲突的问题。例如在本例中若两个线程同时访问变量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+"\n");    }        /*     * 取款操作     * @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+"\n");        }        else            System.out.println("余额不足!");    }        }

 

某次运行结果: