Java在同步块中调用其他方法
我编写了一个工人类,如下所示:Java在同步块中调用其他方法,java,multithreading,synchronization,Java,Multithreading,Synchronization,我编写了一个工人类,如下所示: 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
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);
}
}
}
}
我在main方法中启动两个新线程,并在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,
整个实例被其他线程阻塞,并将通过离开同步块来释放。
如果我在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
有人能告诉我它是怎么工作的吗?谢谢 关于
synchronized
的含义和用法,您弄错了。如果您声明了一个方法synchronized
,它在功能上等同于在方法体的整个内容周围放置一个synchronized(this){…}
块。这与同一对象的其他同步方法以及同一对象上同步的其他块进行交互,但对其他代码没有影响
特别是,在同一对象上不同步的方法和块——或者根本不同步的方法和块——不会被排除在与给定对象的同步方法并发运行的范围之外。因此,未同步的
sync.methodTwo()
可以与sync.MethodOne()
同时运行。防止这种情况发生的许多方法之一是使SynchronizedMultiMethod.methodTwo()
也同步。您对synchronized
的含义和用法理解错误。如果您声明了一个方法synchronized
,它在功能上等同于在方法体的整个内容周围放置一个synchronized(this){…}
块。这与同一对象的其他同步方法以及同一对象上同步的其他块进行交互,但对其他代码没有影响
特别是,在同一对象上不同步的方法和块——或者根本不同步的方法和块——不会被排除在与给定对象的同步方法并发运行的范围之外。因此,未同步的
sync.methodTwo()
可以与sync.MethodOne()
同时运行。防止这种情况的许多方法之一是使SynchronizedMultiMethod.methodTwo()
也同步化
1.在实例级别
2.班级层面
在实例级别,我们在同步方法中传递实例,如
已同步(此)
- 公共同步void methodOne(Worker-sWorker){ sWorker.doSomething();}
在上面的代码中,我们只是传递我们希望同步的实例。java中的synchronized关键字有两种使用方式 1.在实例级别 2.班级层面 在实例级别,我们在同步方法中传递实例,如 已同步(此)
- 公共同步void methodOne(Worker-sWorker){ sWorker.doSomething();}
在上面的代码中,我们只是传递我们希望同步的实例。调用同步方法只会阻塞同一实例上的其他同步器。由于
methodTwo()
未同步,因此它不会被阻止。如果doSomething
是同步的,而不是methodOne
,它应该可以正常工作。关于计算部分,如果您只是想让线程在那里花费一些时间,您可以尝试使用Thread.sleep
。John Bollinger的答案可以归结为:synchronized(foo){…}
防止其他线程同时对同一对象foo
执行synchronized(foo){…}
。它不会阻止其他线程执行任何其他操作。调用同步方法只会阻止同一实例上的其他同步器。由于methodTwo()
未同步,因此它不会被阻止。如果doSomething
是同步的,而不是methodOne
,它应该可以正常工作。关于计算部分,如果您只是想让线程在那里花费一些时间,您可以尝试使用Thread.sleep
。John Bollinger的答案可以归结为:synchronized(foo){…}
防止其他线程同时对同一对象foo
执行synchronized(foo){…}
。它不会阻止其他线程执行任何其他操作。
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