免责声明:此代码是从synchronized blocks for static and non-static methods
复制的我对它做了一些修改。我想知道如何使线程调用同步静态和非静态方法。我可以通过将非静态方法包装在同步块中来使其工作。还有其他办法吗?
public class StaticNonStaticSynch
{
public static void main(String[] args)
{
final StaticNonStaticTest staticNonStaticTest = new StaticNonStaticTest();
Runnable runnable1 = new Runnable()
{
@Override
public void run()
{
staticNonStaticTest.nonStaticMethod();
}
};
Runnable runnable2 = new Runnable()
{
@Override
public void run()
{
StaticNonStaticTest.staticMethod();
}
};
Thread thread1 = new Thread(runnable1, "First Thread");
Thread thread2 = new Thread(runnable2, "Second Thread");
thread1.start();
thread2.start();
}
}
class StaticNonStaticTest
{
void nonStaticMethod()
{
//synchronized (StaticNonStaticTest.class){
for(int i=0;i<50;i++)
{
System.out.println("Non - Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
// }
}
static synchronized void staticMethod()
{
for(int i=0;i<50;i++)
{
System.out.println("Static method called by " + Thread.currentThread().getName() +" : = "+i);
}
}
}
答案 0 :(得分:4)
请记住:
public class MyClass {
public synchronized void doSomething() {
// Do something
}
public synchronized static void doSomethingStatic() {
// Do something static
}
}
基本上可以编译:
public class MyClass {
public void doSomething() {
synchronized(this) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MyClass.class) {
// Do something static
}
}
}
请注意,他们不会在同一件事上同步。要解决此问题,请为它们两者创建一个对象以锁定(称为互斥对象,或者#34;互斥体&#34;):
public class MyClass {
private static final Object MUTEX = new Object();
public void doSomething() {
synchronized(MUTEX) {
// Do something
}
}
public static void doSomethingStatic() {
synchronized(MUTEX) {
// Do something static
}
}
}
这应该使得这两个方法中只有一个在多个线程中同时运行。
一些提示:
synchronized(variable)
上使用variable
final
。MUTEX
并非必须严格来说是互斥锁,它可能是一个实际的对象。请参阅下面的示例。synchronized
修饰符。它就像synchronized
或this
上的MyClass.class
阻止一样。除了具有严格意义上的互斥锁的对象外,您还可以使用final
的任何字段。例如,要在迭代期间同步Map
:
public class MyClass {
private static final Map<String, String> map = new HashMap<String, String>(); // Java 6
private static final Map<String, String> map = new HashMap<>(); // Java 7
public static void put(String k, String v) {
synchronized(map) {
map.put(k, v);
}
}
public static void printAll() {
synchronized(map) {
for (Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
}
此代码可确保您永远不会获得ConcurrentModificationException
答案 1 :(得分:2)
您可以让两个方法在公共锁定对象上进行内部同步。否则,在静态方法执行时使实例方法块的唯一方法是在类对象上进行同步(就像在注释行中一样)。
同步实例方法在对象实例上同步; synchronized静态方法在类实例上同步。请注意,如果有两个类实例(例如,来自不同的类加载器),则同步静态方法可能会同时执行。你通常会知道这是否正在发生,因为你必须做大量工作才能实现。
这是在公共锁定对象上同步静态和实例方法的一种方法:
class StaticNonStaticTest {
private static final Object LOCK_OBJECT = new Object();
void nonStaticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Non - Static method called by "
+ Thread.currentThread().getName() + " : = " + i);
}
}
}
static void staticMethod() {
synchronized (LOCK_OBJECT) {
for (int i=0; i<50; i++) {
System.out.println("Static method called by "
+ Thread.currentThread().getName() +" : = "+i);
}
}
}
}