zoukankan      html  css  js  c++  java
  • 关于java多线程任务执行时共享资源加锁的方式思考

    1.加锁方式:

      1-1.使用synchronized关键字进行方法或代码块的加锁方式

      1-2.使用ReentrantLock类提供的lock()方法的方式

    2.代码实现(传统的银行取款存款问题):

      2-1.Account.java类:账户类

    package com.java.thread;
    
    import java.util.concurrent.locks.ReentrantLock;
    /**
     * 账户类
     * @author steven
     *
     */
    public class Account {
    
        public double money = 6000;
        public ReentrantLock lock = new ReentrantLock();
        public Account(double money){
            this.money = money;
        }
        public void drawmoney(double money,String name){
            synchronized (this) {
                this.money -= money;
                System.out.println(name+"取款后剩余钱数:"+this.money);
            }
        }
        
        public void drawmoney1(double money,String name){
            lock.lock();
            try {
                this.money -= money;
                System.out.println(name+"取款后剩余钱数:"+this.money);
            }catch (Exception e) {
                // TODO: handle exception
            }finally{
                lock.unlock();
            }
        }
        
        public synchronized void cunmony(double money,String name){
                this.money += money;
                System.out.println(name+"存款后剩余钱数:"+this.money);
        }
        
    }
    View Code

      2-2.User.java类:线程实现类

    package com.java.thread;
    
    /**
     * 继承线程类,重写run方法
     * @author steven
     *
     */
    public class User extends Thread{
    
        private String username;
        private Account account;
        public User(String username,Account account){
            this.username = username;
            this.account = account;
        }
        public void run(){
            if (username.contains("0")||username.contains("1")||username.contains("2"))
                this.account.cunmony(1000,username);
            else if(username.contains("3"))
                this.account.drawmoney(500, username);
            else
                this.account.drawmoney1(100, username);
        }
        public static void main(String[] args) {
            Account account = new Account(10000);
            User user = null;
            for (int i = 0; i < 5; i++) {
                user = new User("user"+i, account);
                user.setPriority(i+1);
                user.start();
            }
        }
    }
    View Code

    3.误区总结:

      账户在这一问题中就算是多线程问题中的共享资源,在线程实现类中,我们需要使用构造函数的方式将该资源定义到该类的构造函数里,在具体多线程操作时创建唯一的资源,并将其放入新建线程的构造函数中,这样就能实现模拟多个线程操作同一资源的效果。

  • 相关阅读:
    sqlserver建立临时表
    动态引用WebService
    技术的力量:30分钟的动画片和《彗星撞地球》超炫的动画 仅64K
    sqlserver2005新功能函数
    使用面向对象的、完整的单点登录功能
    asp.net上传功能(单文件,多文件,自定义生成缩略图,水印)
    C#对字符和文件的加密解密类
    JavaScript中setInterval函数应用常见问题之一(第一个参数不加引号与加引号的区别)
    JavaScript表格隔行换色悬停高亮
    Javascript模拟c#中arraylist操作(学习分享)
  • 原文地址:https://www.cnblogs.com/g177w/p/9909340.html
Copyright © 2011-2022 走看看