多线程环境下,我们在一个线程中操作某个对象过程中,不想让其它线程在此区间内对该对象进行(某些)操作。
注:一般是指读写操作
需要通过一个第三方对象来协调多个线程的行动。这个第三方对象就是一个令牌发放器。
注:线程是多个的,相应的同步对象及令牌只能有一个,否则起不到同步作用。比如在一个方法前加上synchronized关键字,那么作为同步对象(令牌发放器)的就是类实例(对象)。如果我们创建了一个例实例(对象),在多个线程中调用synchronized关键字所修饰的方法,那么可以起到同步作用。但如果创建了多个类实例,那么在方法前加synchronized关键字就起不到同步作用了。比如下面:
class MyThread implements java.lang.Runnable
{
private int threadId;
public MyThread(int id)
{
this.threadId = id;
}
@Override
public synchronized void run()
{
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);
}
}
}如果存在多个实例,那么解决办法就是使用外部对象或静态成员作为同步对象:
class MyThread implements java.lang.Runnable
{
private int threadId;
private Object lock;
public MyThread(int id, Object obj)
{
this.threadId = id;
this.lock = obj;
}
@Override
public void run()
{
synchronized(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
{
Object obj = new Object();/******注意这里作为同步对象的外部对象!******/
for (int i = 0; i < 10; ++i)
{
new Thread(new MyThread(i, obj)).start();
Thread.sleep(1);
}
}
}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)
{
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);
}
}
}synchronized的令牌是单一属性,一个线程中某段代码先申请到了该令牌后,其它线程中等待该令牌的代码都暂时不能执行。而另一种令牌读写锁则较为灵活。它的规则是:一个线程中代码申请到了写令牌,其它线程中等待读令牌和写令牌的代码都暂时不能执行。一个线程申请到了读令牌,其它线程中等待写令牌的代码暂时不能执行。
3531

被折叠的 条评论
为什么被折叠?



