synchronized关键字: 当synchronized关键字修饰一个方法的时候,该方法叫做同步方法。
Java中的每个对象都有一个锁,或者叫监视器,当访问某个对象的synchronized方法时,表示
将该对象上锁,此时其他任何线程都无法再去方法该synchronized方法了,知道之前的那个线程
执行方法完毕后(或者抛出异常),那么将该对象的锁释放掉,其他线程才有可能再去访问该synchronized方法。
实例代码demo:
public class FetchMoney
{
public static void main(String[] args)
{
Bank bank = new Bank();
Thread t1 = new MoneyThread(bank);
Thread t2 = new MoneyThread(bank);
t1.start();
t2.start();
}
}
class Bank
{
private int money = 1000;
public synchronized int getMoney(int number)
{
if(number < 0)
{
return -1;
}
else if(number > money)
{
return -2;
}
else
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
money -= number;
return number;
}
}
}
class MoneyThread extends Thread
{
private Bank bank;
public MoneyThread(Bank bank)
{
this.bank = bank;
}
@Override
public void run()
{
System.out.println(bank.getMoney(800));
}
}
值得强调的是 synchronized关键字 锁的是对象,而不是对象的方法
如果某个synchronized方法是static的,那么当线程访问该方法时,
他锁的不是synchronized方法锁在的对象。而是
synchronized方法锁在的对象所对应的class对象,
因为Java中无论一个类有多少个对象,这些对象会对应唯一一个class对象,
因此当线程分别访问同一个类的两个对象的两个static,synchronized方法时,他们执行顺序也是顺序的,
也就是说一个线程先去执行方法,执行完毕后才另一个线程才开始执行。
synchronized 代码块简单代码实例片段
class Test
{
Object obj = new Object();
public void execute()
{
synchronized(obj)
{
for(int i = 0 ; i < 20 ; i++)
{
try
{
Thread.sleep((long) (Math.random * 1000));
}
catch(InterruptedExeception e)
{
e.printStackTrace();
}
}
}
public void execute2()
{
synchronized(obj)
{
for(int i = 0 ; i < 20 ; i++)
{
try
{
Thread.sleep((long) (Math.random * 1000));
}
catch(InterruptedExeception e)
{
e.printStackTrace();
}
}
}
}
}
synchronized代码块只是将方法里的部分代码设置同步更加细粒度,synchronized直接去修饰方法太粗粒度某一个时刻只能有一个线程访问该方法