zoukankan      html  css  js  c++  java
  • 线程之同步方法

    线程同步方法:

    synchronized修饰方法:

    1.非静态方法: 默认的同步监听器对象 this
    2.静态方法: 默认的同步监听器对象 是该方法所在类的 Class对象 ooxx.class

    若线程是实现方式:
    :同步代码块: 同步监听对象可以选 this, 这个方法所在类的Class对象, 选一个不变对象
    :同步方法: 此时可以使用synchronized直接修饰 run方法,因为同步监听器 是 this;

    class Account {
    private double banlance;

    public Account(Double d) {
    this.banlance = d;

    }

    public double getBanlance() {
    return banlance;
    }

    public void setBanlance(double banlance) {
    this.banlance = banlance;
    }
    }

    class ATM implements Runnable {
    private Account a;
    private double drawMoney;

    public ATM(Account a, double drawMoney) {
    this.a = a;
    this.drawMoney = drawMoney;
    }

    @Override
    public void run() {
    // TODO Auto-generated method stub
    synchronized (this) {
    /**
    * 若同步代码块使用this作为同步监听器对象,那么直有实现Runnable才可以使用
    */
    if (a.getBanlance() > drawMoney) {
    System.out.println(Thread.currentThread().getName() + "取走"
    + drawMoney + "元");
    a.setBanlance(a.getBanlance() - drawMoney);
    System.out.println(Thread.currentThread().getName() + "還剩"
    + a.getBanlance() + "元");
    } else {
    System.out.println(Thread.currentThread().getName() + "余额不足"
    + a.getBanlance());
    }
    }

    }
    }

    public class DrawMoneyDemo {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    Account acount = new Account(1000.00);
    ATM a = new ATM(acount, 800);
    new Thread(a, "A").start();
    new Thread(a, "B").start();
    }

    }

    卖票例子用任意对象修饰,用Object   o

    class MyRunnable implements Runnable{
    private Integer num=50;
    @Override
    public void run() {
    // TODO Auto-generated method stub
    for(int i=0;i<200;i++){
    sale();
    }
    }
    private Object o = new Object();
    public void sale(){
    synchronized(o){
    if(num>0){
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"卖出了第"+num--+"张");
    }
    }
    }
    }
    public class TickDemoSynchByblock {
    public static void main(String args[]){
    Runnable r=new MyRunnable();
    new Thread(r,"A").start();
    new Thread(r,"B").start();
    new Thread(r,"C").start();
    }
    }

    若线程时继承方式:
    :同步代码块: 这个方法所在类的Class对象, 选一个不变对象
    :同步方法: 此时不能使用synchronized直接修饰 run方法

    请看下方例子

    class Account2 {
    public double banlacne;
    public double getBanlacne() {
    return banlacne;
    }

    public void setBanlacne(double banlacne) {
    this.banlacne = banlacne;
    }

    public Account2(double b) {
    this.banlacne = b;
    }

    public synchronized void drawMoney(double drawMoney) {
    // TODO Auto-generated method stub
    if (banlacne > drawMoney) {
    System.out.println(Thread.currentThread().getName() + "-->,吐出"
    + drawMoney);
    setBanlacne(banlacne - drawMoney);
    System.out.println(Thread.currentThread().getName() + "剩余"
    + banlacne);
    } else {
    System.out.println(Thread.currentThread().getName() + "余额不足"
    + getBanlacne());
    }
    }
    }

    class ATM2 extends Thread {
    private double drawMoney;
    private Account2 a;

    public ATM2(double drawMoney, Account2 a, String name) {
    super(name);
    this.drawMoney = drawMoney;
    this.a = a;
    }

    public void run() {
    a.drawMoney(drawMoney);
    }
    }

    public class CopyOfDrawMoney {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    Account2 a = new Account2(1000.00);
    new ATM2(800, a, "A").start();
    new ATM2(800, a, "B").start();
    }

    }

    取钱的例子,不能用Synchronized 直接修饰run方法

    第三种 ReentrantLock

    格式:
    *
    * private final ReentrantLock lock= new ReentrantLock();//创建锁的一个对象
    *
    * public void m(){
    * //进入方法第一件事,上锁
    * lock.lock();//获取锁
    *
    * try{
    * //需要同步的代码
    * }finally{
    * lock.unlock();//解锁,走人
    * }
    *
    *
    * }

    请看例子

    class Account{
    private double banlance;
    private final ReentrantLock lock= new ReentrantLock();
    public Account(double banlance) {
    super();
    this.banlance = banlance;
    }
    public double getBanlance() {
    return banlance;
    }

    public void setBanlance(double banlance) {
    this.banlance = banlance;
    }
    public void drawMoney(double drawMoney ){
    lock.lock();   //上锁
    try{
    if(getBanlance()>=drawMoney){
    System.out.println(Thread.currentThread().getName()+"取出"+drawMoney);
    setBanlance(getBanlance() - drawMoney);
    System.out.println(Thread.currentThread().getName() + "剩余"
    + getBanlance());
    } else {
    System.out.println(Thread.currentThread().getName() + "余额不足"
    + getBanlance());
    }
    }finally{
    lock.unlock();  // 放锁
    }
    }
    }
    class ATM extends Thread{
    private Account a;
    private double drawMoney;
    public ATM(double drawMoney, Account a, String name) {
    super(name);
    this.drawMoney = drawMoney;
    this.a = a;
    }

    public void run(){
    a.drawMoney(drawMoney);
    }
    }

    public class DrawMoneyDemo {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    Account a = new Account(1000);
    new ATM(800, a, "A").start();
    new ATM(800, a, "B").start();
    }

    }

    卖票例子

    class MyRunnabl implements Runnable{
    private Integer num=50;
    @Override
    public void run() {
    // TODO Auto-generated method stub
    for(int i=0;i<50;i++){
    sale();
    }
    }
    public synchronized void sale(){
    if (num > 0) {
    try {
    Thread.sleep(1);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "卖出第" + num--
    + "张");
    }
    }
    }

    public class TicketDemoSynchByblock2 {

    public static void main(String[] args) {
    // TODO Auto-generated method stub
    MyRunnabl t=new MyRunnabl();
    new Thread(t,"A").start();
    new Thread(t,"B").start();
    new Thread(t,"C").start();
    }

    }

  • 相关阅读:
    【软件教程】oracle11g数据库的下载和安装
    (一)最新VMware vSphere Data Protection(VDP) 6.1.11 的安装过程
    缓存与库先写哪个,这十几张图告诉你
    因为它,差点无缘大厂梦!!!
    从小公司进入大厂,我都做对了哪些事?
    毕业一年后接私活赚了10w,还拿了几家大厂offer!
    同样是持久化,竟然有这么大的差别!
    硬核!15张图解Redis为什么这么快
    面试时说Redis是单线程的,被喷惨了!
    【漫画】活见鬼,明明删除了数据,空间却没减少!
  • 原文地址:https://www.cnblogs.com/lixiaowei395659729/p/7141667.html
Copyright © 2011-2022 走看看