- synchronized只能修饰方法,和修饰一个代码块!
-
//修饰一个块
syschronized(一个对象)
{
。。。。
}
java中的每一个对象都有一个锁(lock),或者叫监视器,当这个对象访问一个synchronized方法的时候,表示将这个对象上锁,此时其它任何线程都无法再去访问这个synchronized方法了!直到之前那个线程执行完毕方法后或者抛出异常,那么将该对象的锁释放掉,其它线程就可以访问该synchronized方法。
- 如果一个对象有多个synchronized方法,在某一时刻,一个线程进入到某个synchronized方法后,那么在这个方法没有执行完毕前,其它线程是无法访问该对象的任何synchronized方法!
- 如果有多个对象多个线程访问一个synchronized方法,这样情况下,多个线程都会随机的去访问该方法,只会锁住对应的对象。
- //如果有多个对象多个线程访问一个static synchronized的方法,则此方法每次只允许一个对象调用
- 如果某个syschronized方法是static的,那么当多个线程访问这个方法的时候,它锁的不是synchronized方法所在的的对象,而是锁的是所在对象对应的Class对象,因为java中无论有多少个对象,这些对象会对应一个Class对象,因此当线程分别访问同一个类的多个对象的static synchronized方法时,他们的执行顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后,另一个线程才开始执行。
- 下面的代码,请根据上面的规则自己修改,然后测试
package com.yuxi.lesson102;
public class SynchronizedDemo
{
public static void main(String[] args)
{
Event event = new Event();
Event event2 = new Event();
MyThread1 myThread = new MyThread1(event);
MyThread2 myThread2 = new MyThread2(event2);
new Thread(myThread).start();
new Thread(myThread2).start();
Event.doThingOne();
}
}
class Event
{
public static synchronized void doThingOne()
{
for (int i = 0; i <20; i++)
{
try
{
Thread.sleep((long) (Math.random()*100));
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("事情1正在做"+i);
}
System.out.println("做完了事情1");
}
public synchronized void doThingTwo()
{
for (int i = 0; i <20; i++)
{
try
{
Thread.sleep((long) (Math.random()*100));
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("事情2正在做"+i);
}
System.out.println("做完了事情2");
}
}
class MyThread1 implements Runnable
{
private Event event;
public MyThread1(Event event)
{
this.event = event;
}
@Override
public void run()
{
this.event.doThingOne();
}
}
class MyThread2 implements Runnable
{
private Event event;
public MyThread2(Event event)
{
this.event = event;
}
@Override
public void run()
{
this.event.doThingOne();
}
}