synchronized方法和synchronized块
synchronized方法必须获得对象的锁才能执行,否则线程阻塞,方法一旦执行,就独占此锁,直到方法返回才释放锁,后面被阻塞的线程才能获得这个锁,继续执行
synchronized会影响效率
同步块synchronized(Obj){},Obj是同步监听器,第一个线程访问,所定Obj,完后解锁Obj,第二个才能访问
同步方法弊端:方法里面需要修改的内容才需要锁,锁的太多,浪费资源
package com.wuming.syn.synch; //不安全的买票 public class UnSafeBuyTicket {public static void main(String[] args) {BuyTicket station = new BuyTicket();new Thread(station,"苦逼的我").start();new Thread(station,"牛逼的你们").start();new Thread(station,"可恶的黄牛党").start();} }class BuyTicket implements Runnable{//票private int ticketNums=10;boolean flag=true;//停止方式/*** When an object implementing interface <code>Runnable</code> is used* to create a thread, starting the thread causes the object's* <code>run</code> method to be called in that separately executing* thread.* <p>* The general contract of the method <code>run</code> is that it may* take any action whatsoever.** @see Thread#run()*/@Overridepublic void run() {//买票while(flag){try {buy();} catch (InterruptedException e) {e.printStackTrace();}}}//synchronized同步方法,锁的是this BuyTicketprivate synchronized void buy() throws InterruptedException {//判断是否有票if (ticketNums<=0){flag=false;return;}//模拟延时Thread.sleep(100);//买票System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);//加了synchronized,安全/* 苦逼的我拿到10可恶的黄牛党拿到9可恶的黄牛党拿到8牛逼的你们拿到7可恶的黄牛党拿到6苦逼的我拿到5苦逼的我拿到4可恶的黄牛党拿到3牛逼的你们拿到2可恶的黄牛党拿到1*/} }
===============
package com.wuming.syn; //不安全的取钱 //两个人去银行取钱,账户 public class UnSafeBank {public static void main(String[] args) {//账户Account account = new Account(100,"结婚基金");Drawing you = new Drawing(account,50,"你");Drawing girlFriend = new Drawing(account,100,"girlFriend");you.start();girlFriend.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);//线程namethis.account = account;this.drawingMoney = drawingMoney;this.nowMoney = nowMoney;} //取钱//synchronized默认锁的是本身@Overridepublic void run() {//锁的对象是变化的量,增删改;改成this就是指银行,线程不安全如下/* 结婚基金余额为:-50结婚基金余额为:-50你手里的钱50girlFriend手里的钱100*/synchronized (account){//判断有没有钱if(account.money-drawingMoney<0){System.out.println(Thread.currentThread().getName()+"钱不够,取不了");return;}//sleep可以放大问题的发生性try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//卡内余额=余额-你取的钱account.money=account.money-drawingMoney;//你手里的钱nowMoney=nowMoney+drawingMoney;System.out.println(account.name+"余额为:"+account.money);//Thread.currentThread().getName()=this.getName();System.out.println(this.getName()+"手里的钱"+nowMoney);}//使用同步块 synchronized (account),线程安全/* 结婚基金余额为:50你手里的钱50girlFriend钱不够,取不了*/} }
===============
package com.wuming.syn.synch;import java.util.ArrayList; import java.util.List;//线程不安全的集合 public class UnsafeList {public static void main(String[] args) {List<String> list=new ArrayList<String>();for (int i = 0; i < 10000; i++) {new Thread(()->{synchronized (list){//线程安全list.add(Thread.currentThread().getName());}}).start();}try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(list.size());//每次运行都不够10000,线程不安全,两个线程同时操作同一个位置,//两个数组添加到同一个位置,就会覆盖掉,元素就会少} }
10000