• 多线程之线程安全


    首先还是贴上原博主网址,感谢原博主的分享https://home.cnblogs.com/u/lwbqqyumidi

    内容很多我借鉴到,经过理解后编辑如下:

    什么是线程安全呢
    就是一个线程在执行的时候,失去了cpu资源,程序去执行另外一个线程了,而该线程执行体或者说一段代码是不能间断的,间断就会产生问题,这样就会出现线程不安全的情况
    看下面的例子就明白了:

     1 class Account {
     2 
     3     private String accountNo;//账号
     4     private double balance;//余额
     5 
     6     public Account() {
     7 
     8     }
     9 
    10     public Account(String accountNo, double balance) {
    11         this.accountNo = accountNo;
    12         this.balance = balance;
    13     }
    14 
    15     public String getAccountNo() {
    16         return accountNo;
    17     }
    18 
    19     public void setAccountNo(String accountNo) {
    20         this.accountNo = accountNo;
    21     }
    22 
    23     public double getBalance() {
    24         return balance;
    25     }
    26 
    27     public void setBalance(double balance) {
    28         this.balance = balance;
    29     }
    30 
    31 }
     1 class DrawMoneyRunnable implements Runnable {
     2     private Account account;
     3     private double drawAmount;//取钱数
     4     public DrawMoneyRunnable(Account account, double drawAmount) {
     5         super();
     6         this.account = account;
     7         this.drawAmount = drawAmount;
     8     }
     9     //取钱
    10     public void run(){
    11                 if (account.getBalance() >= drawAmount) {
    12                     System.out.println("取钱人:"+Thread.currentThread().getName()
    13                             +"取钱成功, 取出钱数为:" + drawAmount);
    14                     double balance = account.getBalance() - drawAmount;
    15                     account.setBalance(balance);
    16                     System.out.println("余额为:" + balance);
    17                 }
    18     }
    19 }
     1 public class ThreadTest {
     2     public static void main(String[] args) {
     3         Account account = new Account("123456", 1000);
     4         DrawMoneyRunnable drawMoneyRunnable = new DrawMoneyRunnable(account, 700);
     5         Thread myThread1 = new Thread(drawMoneyRunnable);
     6         Thread myThread2 = new Thread(drawMoneyRunnable);
     7         myThread1.start();
     8         myThread2.start();
     9     }
    10 }

    运行结果,发现是有问题的,因为线程执行体中代码必须是不间断执行的,这样线程不安全....

    1.同步方法

    public synchronized void run(){

    }

    对共享资源(account对象)进行访问的方法定义中加上synchronized关键字修饰,使得此方法称为同步方法。可以简单理解成对此方法进行了加锁,其锁对象为当前方法所在的对象自身(是指该线程对象吗?)。多线程环境下,当执行此方法时,首先都要获得此同步锁(且同时最多只有一个线程能够获得),只有当线程执行完此同步方法后,才会释放锁对象,其他的线程(是指该线程类创建的其它对象吗?)才有可能获取此同步锁,以此类推...

    在上例中,共享资源为account对象,当使用同步方法时,可以解决线程安全问题。只需在run()方法前加上synshronized关键字即可

    上面的一段话是原博主写的,不是很理解,只要简单记住加锁后,该方法就会不间断的执行完....

    2.同步代码块

    有时需要的只是一段代码不间断执行,这就是同步代码块

    synchronized (obj){

    }

    其中,obj为锁对象,一般情况下,都是选择此共享资源对象作为锁对象

    如上例中,共享资源就是account对象啊,因为都是在取同一个账号的钱,所以最好选用account对象作为锁对象

    也可以使用this,就是指执行run方法的该线程对象

    1 public void run(){
    2         //循环取钱
    3         for (int i = 0; i < 1000; i++) {
    4             synchronized (this){//加锁
    5                          ......
    6             }
    7     }
    8 }

    3.还有其它的等待,唤醒以后在来研究....

  • 相关阅读:
    C#中创建Android项目
    C#中创建Android项目
    在C#中获取当前屏幕的分辨率的方法
    数据库面试
    计算机网络面试
    linux面试
    Java使用递归检索文件个数
    二分查找
    富途证券面经(一面挂)
    Mysql
  • 原文地址:https://www.cnblogs.com/jaro/p/8907937.html
Copyright © 2020-2023  润新知