Java 在同步块中调用其他方法
Java calling other methods in synchronized block
我写了一个工人 class 看起来像这样:
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);
}
}
}
}
之后我打电话给工人 class:
public class SynchronizedMultiMethod
{
public synchronized void methodOne()
{
Worker.doSomething();
}
public void methodTwo()
{
Worker.doSomething();
}
}
我在主方法中启动了两个新线程,并在 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
...
我有点困惑,因为我认为如果我在实例方法上使用同步,
整个实例被其他线程阻塞,将通过离开同步块来释放。
如果我在 methodTwo() 上使用第二个同步,它工作正常:
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
谁能告诉我它是如何工作的?谢谢!
您对synchronized
的含义和用法有误。如果声明一个方法 synchronized
,它在功能上等同于在方法主体的整个内容周围放置一个 synchronized(this) {...}
块。这与同一对象的其他同步方法交互,并与同一对象上的其他同步块交互,但对其他代码没有影响。
特别是,在同一对象上不同步的方法和块——或者根本不同步的——不会被排除在运行与给定对象的同步方法并发的范围之外。因此,未同步的 sync.methodTwo()
可以与 sync.MethodOne()
同时 运行。防止这种情况的许多方法之一是使 SynchronizedMultiMethod.methodTwo()
也同步。
java中的synchronized关键字有两种用法
1.At 实例级别
2.At Class 级别
在实例级别,我们在同步方法中传递实例,例如
同步(这)
- public synchronized void methodOne(Worker sWorker) {
sWorker.doSomething(); }
在上面的代码中,我们只是传递了我们愿意同步的实例。
我写了一个工人 class 看起来像这样:
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);
}
}
}
}
之后我打电话给工人 class:
public class SynchronizedMultiMethod
{
public synchronized void methodOne()
{
Worker.doSomething();
}
public void methodTwo()
{
Worker.doSomething();
}
}
我在主方法中启动了两个新线程,并在 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
...
我有点困惑,因为我认为如果我在实例方法上使用同步, 整个实例被其他线程阻塞,将通过离开同步块来释放。 如果我在 methodTwo() 上使用第二个同步,它工作正常:
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
谁能告诉我它是如何工作的?谢谢!
您对synchronized
的含义和用法有误。如果声明一个方法 synchronized
,它在功能上等同于在方法主体的整个内容周围放置一个 synchronized(this) {...}
块。这与同一对象的其他同步方法交互,并与同一对象上的其他同步块交互,但对其他代码没有影响。
特别是,在同一对象上不同步的方法和块——或者根本不同步的——不会被排除在运行与给定对象的同步方法并发的范围之外。因此,未同步的 sync.methodTwo()
可以与 sync.MethodOne()
同时 运行。防止这种情况的许多方法之一是使 SynchronizedMultiMethod.methodTwo()
也同步。
java中的synchronized关键字有两种用法 1.At 实例级别 2.At Class 级别
在实例级别,我们在同步方法中传递实例,例如 同步(这)
- public synchronized void methodOne(Worker sWorker) { sWorker.doSomething(); }
在上面的代码中,我们只是传递了我们愿意同步的实例。