A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© a80C51 中级黑马   /  2015-9-28 23:49  /  200 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1)同步代码块
        定义:使用同步监视器来解决线程冲突的问题,实现该同步监视器的通用方法。
2)语法结构
  1. package com.example.bankthread;

  2. public class BankAccountDrawThread extends Thread {
  3.         private BankAccount bankAccount;
  4.         private double drawAmount;
  5.        
  6.         public BankAccountDrawThread(String name,BankAccount account,double drawAccount) {
  7.                 // TODO Auto-generated constructor stub
  8.                 super(name);
  9.                 this.bankAccount = account;
  10.                 this.drawAmount = drawAccount;
  11.         }
  12.        
  13.         @Override
  14.         public void run() {
  15.                 // TODO Auto-generated method stub
  16.                 /*
  17.                  * 使用bankAccount作为同步监视器,
  18.                  * 任何线程在进入同步代码块之前,都会先获取对bankAccount的锁定,
  19.                  * 此时,其他线程无法获得锁,也就无法修改它
  20.                  *
  21.                  */
  22.                 synchronized(bankAccount)
  23.                 {
  24.                         if(bankAccount.getBalance()>= drawAmount)
  25.                         {
  26.                                 System.out.println(getName()+"取钱成功,出钞:"+drawAmount);
  27.         /*                        try {
  28.                                         Thread.sleep(1);
  29.                                 } catch (InterruptedException e) {
  30.                                         // TODO Auto-generated catch block
  31.                                         e.printStackTrace();
  32.                                 }*/
  33.                                 bankAccount.setBalance(bankAccount.getBalance()-drawAmount);
  34.                                 System.out.println("\t余额为:"+bankAccount.getBalance());
  35.                         }
  36.                         else
  37.                         {
  38.                                 System.out.println(getName()+"取钱失败!余额不足!");
  39.                         }
  40.                 }
  41.         }
  42.        
  43.         public static void main(String[] args) {
  44.                 BankAccount bankAccount = new BankAccount("1234567", 10000);
  45.                
  46.                 new BankAccountDrawThread("甲", bankAccount, 8000).start();
  47.                 new BankAccountDrawThread("乙", bankAccount, 8000).start();
  48.         }

  49. }
复制代码

3)所代表含义
        线程开始执行同步代码块之前,必须先获得对同步监视器的锁定。
4)逻辑思想
        加锁---》修改---》释放锁。
5)同步方法:
        使用synchronized关键字来修饰某个方法
6)语法结构
  1. package com.example.bankthread;

  2. public class AccountDrawThread extends Thread {
  3.        
  4.         private Account account;
  5.         private double drawAmount;
  6.        
  7.         //设置线程的名字,对应的账户及所需取得钱
  8.         public AccountDrawThread(String name,Account account,double drawAmount) {
  9.                 super(name);//调用父类Thread类中的方法,为线程指定线程名称
  10.                 this.account = account;
  11.                 this.drawAmount = drawAmount;
  12.         }
  13.        
  14.         @Override
  15.         public void run() {
  16.                 // TODO Auto-generated method stub
  17.                 /*
  18.                  * 由于draw()方法,使用synchronized修饰,故此时同步监视器是this,
  19.                  * 故多线程在调用该accoun时,必须先对account对象加锁
  20.                  */
  21.                 account.draw(drawAmount);
  22.         }
  23. }
复制代码

7)对于synchronized修饰的实例方法而言,无须显示的指定同步监视器,其监视器是this引用指代的对象。
8)线程安全的类的特征:
        A,该类的对象可以被多个线程安全地访问;
        B,每个线程调用该对象的任意方法后,都将得到正确的结果;
        C,每个线程调用该对象的任意方法后,该对象依然保持合理状态。
9)为了减少为实现线程安全而带来的运行效率的损失,线程通常采用如下策略:
        A,不要对线程安全类的所有方法进行同步,只对那些会改变竞争资源(共享资源)的方法进行同步控制;
        B,如果可变类有两种运行环境:单线程和多线程,则应该为该可变类通过两个版本——线程安全版本及线程不安全版本。单线程时,使用线程不安全版本;多线程时,使用线程安全版本。
10)同步监视器的锁定释放
        释放情形如下:
        A,当前线程的同步方法、同步代码块执行结束;
        B,当前线程的同步方法、同步代码块遇到了break或者continue等终止运行;
        C,当前线程的同步方法、同步代码块出现了未处理的Error或Exception,导致了代码块或方法异常结束时;
        D,当前线程执行同步代码块或者同步方法时,程序执行同步监视器对象的wait()方法,当前线程暂停。
        不会释放的情形:
        A,线程执行同步代码块或者同步方法时,程序调用Thread.sleep()、Thread.yield()方法来暂停当前线程的执行,当前线程不会释放同步监视器;
        B,线程执行同步代码块是,其他线程调用了该线程的suspend()方法,将线程挂起,该线程不会释放同步监视器。

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马