正文:
1 首先是車站賣票的不安全例子:
package 多執行緒;
public class 執行緒同步 {
public static void main(String[] args) {
BuyTikcet station=new BuyTikcet();
new Thread(station,"小明").start();
new Thread(station,"小紅").start();
new Thread(station,"小小").start();
}
}
class BuyTikcet implements Runnable{
private int ticketNums=10;
boolean flag=true;
@Override
public void run() {
while (flag){
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void buy() throws InterruptedException {
if(ticketNums<=0){
flag=false;
return;
}
Thread.sleep(700);
System.out.println(Thread.currentThread().getName()+ticketNums--);
}
}
因為就一個物件 (Buyticket) 所以多個執行緒訪問這同一個物件 會出現執行緒不安全的情況 這是把方法加上鎖就可以了

2 銀行取款的不安全實體
package 多執行緒;
public class Bank {
public static void main(String[] args) {
Account account=new Account(100,"結婚基金");
Drawing you=new Drawing(account,50,"you");
Drawing girl=new Drawing(account,100,"girl");
you.start();
girl.start();
}
}
class Account{
int money;
String name;
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
//不涉及多個執行緒操作同一個物件 因為每個取款都是一個物件
//但是在買票那里 多個執行緒操作同一個物件
class Drawing extends Thread{
Account account;
int drawingMoney;
int nowMoney;
public Drawing(Account account,int drawingMoney,String name){
super(name);
this.account=account;
this.drawingMoney=drawingMoney;
}
@Override
public void run() {
//synchronized (account){
if(account.money-drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"錢不夠了");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money=account.money-drawingMoney;
nowMoney=nowMoney+drawingMoney;
System.out.println(account.name+"剩下的錢"+account.money+this.getName());
System.out.println(this.getName()+"手里的錢"+nowMoney);
// }
}
}
可以看到如果還是對run方法加鎖的話 是沒有用的,因為這是多個物件 而不是一個物件,多個物件 碰到方法鎖時,他會發現也沒有別的執行緒來搶占這個物件,所以其實這兩個物件互不干擾 屬于兩個空間,
真正應該加鎖的是account公共資源,所以要使用代碼塊,即上文注釋掉的地方
3 不安全集合
package 多執行緒;
import java.util.ArrayList;
import java.util.List;
public class arraylist集合 {
public static void main(String[] args) throws InterruptedException {
List<String> list=new ArrayList<>();
for (int i = 0; i < 10000; i++) {
synchronized (list){
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
}
Thread.sleep(1000);
System.out.println(list.size());
}
}
在這里加一個睡眠,是為了更好的發現問題,有可能for回圈沒跑完 就跑到下面列印了,然后這里保證安全也是代碼塊鎖住公共資源list
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/395028.html
標籤:其他
上一篇:一次完整的滲透測驗(文末有福利)
下一篇:你下載國家反詐中心APP了嗎
