【发布时间】:2017-03-12 10:04:42
【问题描述】:
class Common
{
public synchronized void synchronizedMethod1()
{
System.out.println("synchronized Method1 called");
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("synchronized Method1 done");
}
public synchronized void synchronizedMethod2()
{
System.out.println("synchronized Method2 called");
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("synchronized Method2 done");
}
}
在上面的类中,我有两个同步方法,我从另一个类的 run 方法调用它们。其他类代码如下:
public class ThreadClass implements Runnable
{
private int id = 0;
private Common common;
public ThreadClass(int no, Common object)
{
common = object;
id = no;
}
public void run()
{
System.out.println("Running Thread " + Thread.currentThread().getName());
try
{
if (id == 11)
{
common.synchronizedMethod1();
}
else
{
common.synchronizedMethod2();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
Common c = new Common();
ThreadClass tc = new ThreadClass(11, c);
ThreadClass tc1 = new ThreadClass(20, c);
Thread t1 = new Thread(tc, "Thread 1");
Thread t2 = new Thread(tc1, "Thread 2");
t1.start();
t2.start();
}
}
从 main 方法我开始两个不同的线程。在运行方法中,我给出了将两个不同的线程发送到不同的同步方法的条件。代码产生的输出是:
Running Thread Thread 2
Running Thread Thread 1
synchronized Method2 called
synchronized Method2 done
synchronized Method1 called
synchronized Method1 done
我的输出问题是: 当线程 2 进入同步方法 2 时,它会打印第三行输出并休眠 1 秒。现在,由于线程 1 没有被任何东西阻塞,所以它应该在第 3 行输出之后执行并打印第 5 行输出,然后应该进入睡眠状态,但是当线程 2 进入睡眠状态时,它不会发生这种情况,它会使线程 1 也睡眠然后第一个线程 2 完成它的执行,之后线程 1 完成它的执行。
如果我从方法中删除同步关键字,则不会发生这种行为。 能否请您解释一下使用和不使用同步关键字处理代码的不同方式背后的原因。
提前致谢。
【问题讨论】:
-
因为线程1没有被任何东西阻塞:它被阻塞了,因为它需要进入同步方法,但是不能因为线程2 已经持有锁(并且在持有时正在睡觉)。这就是同步方法的全部原理。
-
@Nizet:我知道同步关键字的概念,但由于我的程序没有遵循它,这就是为什么我对关键字的工作感到困惑。同样在我的程序中,两个线程都作用于不同的同步方法,所以如果线程 2 阻塞了方法 1 并进入睡眠状态,那么它不应该阻碍作用于其他同步方法的线程 1 的工作。这是我在帖子中询问为什么线程 2 阻止线程 1 进入其他未被自身阻止的同步方法。
标签: java multithreading synchronized