public class BankCard { private static int money=3000; public synchronized void getMoney(String a,int b){ //synchronized (this) { try{ Thread.sleep(1); }catch (InterruptedException e) { // TODO: handle exception } if(money>b){ System.out.println(a+"取走了钱"); money=money-b; }else{ System.out.println(a+"余额不足"); } } //} }
加入synchronized 关键字后结果是 只能取钱一次 ,不加执行两次,synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程(例如线程A),运行到这个方法时,都要检查有没有其它线程B(或者C、 D等)正在用这个方法,有的话要等正在使用synchronized方法的线程B(或者C 、D)运行完这个方法后再运行此线程A,没有的话,直接运行。它包括两种用法:synchronized 方法和 synchronized 块。
public class Runnable1 implements Runnable{ public BankCard bc=new BankCard(); public void run() { // TODO Auto-generated method stub /*for(int i=0;i<10;i++){ if(i==5){ Thread.yield(); } System.out.println("Thread---"+i); }*/ bc.getMoney("张三", 2000); } }
Runnable1 r=new Runnable1(); Thread t=new Thread(r); Thread txin=new Thread(r); /*for(int j=0;j<5;j++){ System.out.println("main--"+j); if(j==2){ try { t.start(); t.join();//合并 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }*/ //创建线程2 Runnable2 t2=new Runnable2("继承"); //t2.setPriority(Thread.MAX_PRIORITY); //t.setPriority(Thread.MIN_PRIORITY); t.start(); //Thread.yield();//通常暂停线程是在线程实体进行 txin.start();
开启俩个线程 同时执行getmoney 方法,加入synchronized的方法会加锁。
2020 新加 对象锁 ,类锁 , 线程关系
package com.zctest.Thread; /** * @Date 2020/6/1 17:32 * @Author zc */ public class Ta extends Thread { public Nei nei; public Ta(Nei nei){ this.nei = nei; } @Override public void run(){ System.out.println(Thread.currentThread().getName()); System.out.println(this.getName()); } public static void main(String[] args) throws InterruptedException { Nei n = new Nei(); //System.out.println(Thread.currentThread().getName()); //Thread s = new Thread(t); Thread t1 = new Thread(()->{ n.a(); }); Thread t2 = new Thread(()->{ n.b(); }); t1.start(); Thread.sleep(1000); t2.start(); } } class Nei { /** * synchronized是对象锁,如果方法a已经获取到该对象锁,则其他调用该实例的b方法的线程要等待锁释放,才能继续执行 * static synchronized 是类锁,指该类的所有实例共用一把锁(注意Nei.a 和 n.a 不是一把锁)
* synchronized(含static sync) 是可重入锁:线程获取对象实例(类)锁后则该线程可以调用该实例(类)的其他sync.修饰的方法 */ public synchronized void a(){ try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("a"); } public synchronized void b(){ System.out.println("b"); } }
2. 以下可以充分说明synchronized(x) 是对象锁。