多线程之线程安全

首先还是贴上原博主网址,感谢原博主的分享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.还有其它的等待,唤醒以后在来研究....

 

posted @ 2018-04-22 16:28  0706jaro  阅读(195)  评论(2编辑  收藏  举报