这里举个例子讲解,同步synchronized在什么地方加,以及同步的前提:
* 1.必须要有两个以上的线程,才需要同步。
* 2.必须是多个线程使用同一个锁。
* 3.必须保证同步中只能有一个线程在运行,锁加在哪一块代码
那么我们要思考的地方有:1.知道我们写的哪些是多线程代码
2.明确共享数据
3.明确多线程运行的代码中哪些语句是操作共享数据的。、
4.要确保多个线程使用同一个锁。
下面的代码:需求:两个存户分别往银行存钱,每次村100块,分三次存完。
第一种写法:使用同步代码块的方式
class bank{ private int sum; Object obj = new Object();//对象锁 public void add(int money){ synchronized (obj) { sum +=money; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("sum="+sum); } } }
第二种方法在函数上加synchronized:
class bank{ private int sum; //函数封装代码(加synchronized)==同步块封装代码 public synchronized void add(int money){ sum +=money; try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("sum="+sum); } } class Cus implements Runnable{ private bank b = new bank(); @Override public void run() { for(int i=0;i<3;i++){ //System.out.println(Thread.currentThread().getName()); b.add(100); } } } public class BankDemo { public static void main(String[] args) { // TODO Auto-generated method stub Cus c1 = new Cus(); Thread t1 = new Thread(c1); Thread t2 = new Thread(c1); t1.start(); t2.start(); } }
总结:同步应该加到add方法上面,因为add方法被run方法调用,所以是线程代码,这里的sum是共享数据,add方法 里面 sum +=money;操作共享数据。这里用了在普通方法上面加syncronized代替同步代码块,这也叫做同步函数。那么同步函数用的锁是什么?我们下一节再接着讨论,多线程同步函数。