zoukankan      html  css  js  c++  java
  • java 多线程 5 : 同步方法

    使用synchronized关键字来修饰某个方法,该方法被称为同步方法。
    对于synchronized修饰的实例方法(非static方法),无需显示指定同步监视器,同步方法的同步监视器是this,也就是调用该方法的对象。
    通过同步方法可以非常方便的实现线程安全的类,线程安全的类具有如下特征:
      该类的对象可以被多个线程对象安全访问
      每个线程调用该对象的任意方法后将得到正确的结果
      每个线程调用该对象的任意方法后,该对象状态依然保持合理状态

    public class Account {
    
        private String account;//账号
        private double balance;//余额
        
        public Account() {
            super();
        }
        public Account(String account, double balance) {
            super();
            this.account = account;
            this.balance = balance;
        }
        
        public synchronized void drawMoney(double drawMoney) {
            if(balance >= drawMoney) {
                System.out.println(Thread.currentThread().getName() + "取钱成功!吐出钞票:" + drawMoney);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                balance -= drawMoney;
                System.out.println("	余额为:" + balance);
            }else {
                System.out.println(Thread.currentThread().getName() + "取钱失败!余额不足");
            }
        }
        
        public String getAccount() {
            return account;
        }
        public void setAccount(String account) {
            this.account = account;
        }
        public double getBalance() {
            return balance;
        }
        public void setBalance(double balance) {
            this.balance = balance;
        }
    }
    public class DrawThread extends Thread{
        private Account account;//模拟账户
        private double drawMoney;//当前取钱线程想要取的钱数
        public DrawThread(String name , Account account, double drawMoney) {
            super(name);
            this.account = account;
            this.drawMoney = drawMoney;
        }
        
        public void run() {
            account.drawMoney(drawMoney);
        }
        
        public static void main(String[] args) {
            Account account = new Account("123456" , 1000);
            new DrawThread("A", account, 800).start();
            new DrawThread("B", account, 800).start();
        }
    }

    使用synchronized关键自修饰drawMoney方法,该方法为同步方法,该同步方法的同步监视器是this,因此,对同一account而言,任意时刻只有一个线程能对account对象锁定,这样可以保障线程安全。

    synchronized关键字只能修饰方法,和代码块。

    线程安全是以降低程序的运行效率作为代价的,为了减少线程安全带来的负面影响
      不要对线程安全类的所有方法都进行同步,对共享资源同步就行了
      如果可变类有两种运行环境,单线程环境/多线程环境,则应该为可变类提供两种版本,线程安全/线程不安全版本,单线程环境中提供线程不安全版本保证性能,多线程环境中使用线程安全版本

    释放同步监听器的锁定:任何线程进入同步代码块,同步监听器,必须先获得对同步监视器的锁定,何时释放呢?
      同步方法/同步代码块执行完了,当前线程,释放同步锁。
      同步方法/同步代码块执行过程中,遇到break,return终止执行,释放同步监视器
      同步方法/同步代码块执行过程中,出现了未处理的error 和 exception , 导致异常结束 , 释放同步监视器
      同步方法/同步代码块执行过程中,程序执行了同步监视器对象的wait()方法,则当前线程暂停,并释放同步监视器


    温故而知新
  • 相关阅读:
    各数据库连接maven配置
    在 windows 下配置 git 公共库
    java笔记2(观察者模式、内部类、输入输出)
    linux 常用命令的应用笔记
    Setting Up Google Code And Github With Git
    java笔记3(单元测试中的模式)
    Apache的配置
    Ubuntu安装常用工具
    MongoDB笔记1(安装配置、用户管理、查询与SQL比较)
    Redis的安装与配置
  • 原文地址:https://www.cnblogs.com/Uzai/p/9675256.html
Copyright © 2011-2022 走看看