1.
public class SynchronizedCounter
{
private int c = 0;`
public synchronized void increment()
{
c++;
}
public synchronized void decrement()
{
c--;
}
public synchronized int value()
{
return c;
}
}
2.
public class MyThread extends Thread
{
private int threadId;
private final static Object obj = new Object();
public MyThread(int threadId)
{
this.threadId = threadId;
}
@Override
public void run()
{
synchronized (obj)
{
for (int i = 0; i < 1000; i++)
System.out.println(this.threadId);
}
}
}
我想提出我的推理,并请你指出它是否正确。
Ex 1所有3个方法都是同步的。它们是非静态的,并在该类的给定实例上同步。这意味着,如果我们有一个SynsynizedCounter类的对象c1,那么如果thread1执行,例如,增量方法,那么这个方法以及所有其他同步方法都被其他线程阻塞,其他线程不能同时调用这些方法。
Ex 2这里我们在最后,重要的是,静态obj对象上阻塞run方法的主体。由于是静态的,它是类的一个属性,因此由该类的所有对象共享,静态obj是MyThread所有实例的公共监视器。所以如果thread1调用run方法,它将在obj对象上阻塞它。并且由于obj对象是静态的,这意味着在阻塞它的线程解除阻塞之前,没有其他线程能够调用这个方法。
不完全是。
#1其他线程不能同时调用这些方法
其他线程CAN调用这些方法,但是它们将被阻止进入该方法,直到同步锁被释放,并且哪个线程访问锁是不确定的。
它相当于同步(this){…}
#2这意味着没有其他线程将无法调用此方法
任何线程都可以调用run方法,但只有单个线程可以获取obj
的锁并进入同步块。
见:
使用同步强制JVM获取和释放锁,即使没有争用。
您应该在#2中查看用于乐观锁定的包java. util.concurrent.lock,并在java.util.concurrent.原子中查看实现#1的更好方法。