* synchronized方法控制对类成员变量的访问:每个类实例对应一把锁,每个被synchronized的方法都必须获得
* 调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释
* 放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声
* 明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),
* 从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为synchronized)。
* 也可以将类的静态成员函数声明为synchronized ,以控制其对类的静态成员变量的访问。
* synchronized方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类
* 的方法run()声明为synchronized,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何synchronized
* 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为synchronized,
* 并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是synchronized块。
*
* synchronized是对同一个对象而言的,即一个对象在执行被synchronized锁定的方法或者代码块时是同步的(不会被打断)
*
*/
public class ThreadTest {
private void method(Object o) throws InterruptedException{
Thread t=Thread.currentThread();
synchronized(t){
for(int i=0;i<10;i++){
System.out.print(t.getName()+" ");
Thread.sleep(100);
}
}
/*
* 把synchronized(t)换成synchronized(o),比较运行结果
* synchronized(o)要求共用一把"锁",所以要求要用同一个对象
* synchronized(o)起到同步效果,synchronized(t)则没同步效果
* 还有:用synchronized修饰method(Object o),看效果
*/
}
public static void main(String args[]){
final ThreadTest th=new ThreadTest();
final Object o=new Object();
Thread t0=new Thread( new Runnable(){
public void run(){
System.out.println("\nT0 Start");
try {
th.method(o);
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("\nT0 End");
}
});
Thread t1=new Thread( new Runnable(){
public void run(){
System.out.println("\nT1 Start");
try {
th.method(o);
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("\nT1 End");
}
});
t0.start();
t1.start();
}
}