🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
我们知道多线程存在一些安全性问题,java为多线程提供给了一个解决多线程安全问题的关键字synchronized。 ### 同步的前提 1、具有两个及以上的线程 2、必须是多个线程使用同一个锁 java提供了Synchronized来解决多线程的安全性问题。 好处:可以解决多线程的安全问题 弊端:每次都要判断锁,耗费系统资源。 ### 同步代码块 synchronized(对象){ //需要加锁的代码块.. } 这个例子演示同步的作用及意义。 ~~~ public class DemoSync{ public static void main(String args[]){ DemoRunnable dr = new DemoRunnable(); Thread t1 = new Thread(dr); Thread t2 = new Thread(dr); Thread t3 = new Thread(dr); Thread t4 = new Thread(dr); t1.start(); t2.start(); t3.start(); t4.start(); } } class DemoRunnable implements Runnable{ private int ticket=100; Object obj = new Object(); //相当于传入的对象锁 public void run(){ while(true){ synchronized(obj){ if(ticket>0){ try{ Thread.sleep(10); }catch(Exception e){} System.out.println(Thread.currentThread().getName()+"--售票:"+ticket--); }else{ System.exit(1); } } } } } ~~~ ### 同步函数的使用 **非静态方法的同步** 即用synchronized修饰非静态的方法。  private synchronized void add(int m) 多线程代码块的对象锁是 this,即当前对象的引用。 **静态方法的同步** 用synchronized修饰静态的方法 因为静态方法进入内存以后并没有产生对象,因此不可能是this, 通过验证,多线程代码块的对象锁是类.class. **问题描述** 有两个储户分别到银行300元,每次存入100元,分3次存储。分析是否存在安全性问题。 如何找问题: 1、明确哪些代码是多线程运行代码 2、明确共享数据 3、明确多线程运行代码中哪些语句是操作共享数据的。 ~~~ public class ThisLockDemo{ public static void main(String args[]){ MyRunnable dr = new MyRunnable(); StaMyRunnable smr = new StaMyRunnable(); Thread t1 = new Thread(smr); Thread t2 = new Thread(smr); t1.start(); t2.start(); } } class MyRunnable implements Runnable{ private int sum = 0; public void run(){ for(int i=0;i<3;i++){ add(100); } } private synchronized void add(int m){ sum += m; System.out.println(Thread.currentThread().getName()+"存储:"+sum); } } class StaMyRunnable implements Runnable{ private static int sum = 0; public void run(){ for(int i=0;i<3;i++){ add(100); } } private static synchronized void add(int m){ sum += m; System.out.println(Thread.currentThread().getName()+"存储:"+sum); } } ~~~