我写了一个看起来像这样的工人阶级:
public final class Worker
{
private static final int LOOP_COUNT = 10;
private static final int COMPUTE_COUNT = 1000;
private static final Random RANDOM = new Random();
private static final int BUFFER_SIZE = 4;
/**
* do a little bit of calculation and write the thread’s name to stdout
*/
public static void doSomething()
{
for (int i = 0; i < LOOP_COUNT; i++)
{
System.out.println("Thread " + Thread.currentThread().getName()
+ " doing something: " + i);
System.out.flush();
for (int j = 0; j < COMPUTE_COUNT; j++)
{
final byte[] buffer = new byte[BUFFER_SIZE];
RANDOM.nextBytes(buffer);
final BigInteger b1 = new BigInteger(buffer);
b1.pow(128);
}
}
}
}
之后我用以下课程给工人打电话:
public class SynchronizedMultiMethod
{
public synchronized void methodOne()
{
Worker.doSomething();
}
public void methodTwo()
{
Worker.doSomething();
}
}
我在main-method中启动了两个新线程,并在SynchronizedMultiMethod中调用了两个方法:
public class Main {
public static void main(String[] args) throws InterruptedException
{
final SynchronizedMultiMethod sync = new SynchronizedMultiMethod();
final Thread t1 = new Thread()
{
public void run()
{
sync.methodOne();
}
};
final Thread t2 = new Thread()
{
public void run()
{
sync.methodTwo();
}
};
t1.start();
t2.start();
}
}
如果我执行此代码,我会得到此输出:
Thread Thread-1 doing something: 0
Thread Thread-0 doing something: 0
Thread Thread-1 doing something: 1
Thread Thread-1 doing something: 2
Thread Thread-1 doing something: 3
Thread Thread-0 doing something: 1
Thread Thread-0 doing something: 2
Thread Thread-1 doing something: 4
...
我有点困惑,因为我认为如果我在实例方法上使用synchronized, 整个实例被其他线程阻塞,并将通过离开synchronized块释放。 如果我在methodTwo()上使用第二个synchronized,它可以正常工作:
Thread Thread-0 doing something: 0
Thread Thread-0 doing something: 1
Thread Thread-0 doing something: 2
Thread Thread-0 doing something: 3
Thread Thread-0 doing something: 4
有谁可以告诉我它是如何工作的?谢谢!
答案 0 :(得分:4)
你误解了synchronized
的含义和用法。如果声明方法synchronized
,则它在功能上等同于在方法体的整个内容周围放置synchronized(this) {...}
块。这与同一对象的其他同步方法交互,并与同一对象上同步的其他块交互,但它对其他代码没有影响。
特别是,在同一对象上未同步的方法和块 - 或者根本不同步 - 并不排除与给定对象的同步方法同时运行。因此,未同步的sync.methodTwo()
可以与sync.MethodOne()
同时运行。防止这种情况的许多方法之一是使SynchronizedMultiMethod.methodTwo()
同步。
答案 1 :(得分:0)
java中的同步关键字有两种使用方式 1.实例级别 2.班级
在实例级别中,我们在synchronized方法中传递实例,如 同步(本)
在上面的代码中,我们只是传递了我们愿意同步的实例。