多线程的同步依靠的是对象锁机制, synchronized 关键字的背后就是利用了封锁来实现对共享资源的互斥访问。 要想实现线程的同步,则这些线程必须去竞争一个唯一的共享的对象锁.
public void synchronized function(){} -> 这个锁的是function这个方法所在的对象, 相当于
public void function() {
synchronized(this ){}
}
public static void synchronized function() ->对于静态方法,锁定的是当前类(假设是类TestClass)的Class对象 ,相当于
public static void function() {
synchronized(TestClass.class ) {}
}
实现同步1. synchronized ( obj ) , 当然是锁obj.在创建启动线程之前,先创建一个线程之间竞争使用的Object对象,然后将这个Object对象的引用传递给每一个线程对象的lock成员变量。这样一 来,每个线程的lock成员都指向同一个Object对象。我们在run方法中,对lock对象使用synchronzied块进行局部封锁 ,这样就可以 让线程去竞争这个唯一的共享的对象锁,从而实现同步。
class MyThread implements java.lang.Runnable
{
private int threadId;
private static Object lock = new Object();
public MyThread( int id)
{
this .threadId = id;
}
@Override
public void run()
{
synchronized (lock) // 共用一个对象锁lock
{
for ( int i = 0 ; i < 100 ; ++ i)
{
System.out.println( " Thread ID: " + this .threadId + " : " + i);
}
}
}
}
public class ThreadDemo
{
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException
{
for ( int i = 0 ; i < 10 ; ++ i)
{
new Thread( new MyThread(i)).start();
Thread.sleep( 1 );
}
}
}
再来看一段代码,实例方法中加入 sychronized 关键字封锁的是 this 对象本身 ,而在静态方法中加入 sychronized 关键字封锁的就是类本身 。静态方法是所有类实例对象所共享的,因此线程对象在访问此静态方法时是互斥访问的,从而可以实现线程的同步,代码如下所示:
代码 package com.vista;
class MyThread implements java.lang.Runnable
{
private int threadId;
public MyThread( int id)
{
this .threadId = id;
}
@Override
public void run()
{
taskHandler( this .threadId);
}
private static synchronized void taskHandler( int threadId)
{
for ( int i = 0 ; i < 100 ; ++ i)
{
System.out.println( " Thread ID: " + threadId + " : " + i);
}
}
}
public class ThreadDemo
{
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException
{
for ( int i = 0 ; i < 10 ; ++ i)
{
new Thread( new MyThread(i)).start();
Thread.sleep( 1 );
}
}
}