[英]thread: Synchronized Block
我对同步块有疑问。 执行以下代码后,输出为:
Inside run=>thread 2
Inside run=>thread 1
Inside run=>thread 1
Inside run=>thread 2
Inside run=>thread 2
Inside run=>thread 1
Inside run=>thread 2
Inside run=>thread 1
Inside run=>thread 1
Inside run=>thread 2
我期望输出,因为只有一个线程会首先执行同步块,然后只有第二个线程才能访问synchornized块。 可能是我了解错误的概念?
package com.blt;
public class ThreadExample implements Runnable {
public static void main(String args[])
{
System.out.println("A");
Thread T=new Thread(new ThreadExample());
Thread T1=new Thread(new ThreadExample());
System.out.println("B");
T.setName("thread 1");
T1.setName("thread 2");
System.out.println("C");
T.start();
System.out.println("D");
T1.start();
}
synchronized public void run()
{
for(int i=0; i<5; i++)
{
try
{
System.out.println("Inside run=>"+Thread.currentThread().getName());
Thread.currentThread().sleep(2000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
您的每个线程都在不同的对象上同步。 所以是的,他们不会互相锁定。 但更重要的是, run
方法是为Runnable
接口定义的, 没有同步修饰符,因此您不应在其中添加一个(如您已经看到的那样,它没有您预期的效果)。
要记住的关键是,当您在方法上使用synced修饰符时:
public synchronized void someMethod();
实际上,它与使用synchronized(this)
。 在这两种情况下,您都锁定在对象监视器上。 如果有多个对象,则有多个监视器。
这是您自己的示例的修改版本,它将按您的预期工作。 它使用一个通用的对象监视器(在本例中为您的类本身),以便同步按预期进行:
public class ThreadExample implements Runnable {
public static void main(String args[]) {
System.out.println("A");
Thread T = new Thread(new ThreadExample());
Thread T1 = new Thread(new ThreadExample());
System.out.println("B");
T.setName("thread 1");
T1.setName("thread 2");
System.out.println("C");
T.start();
System.out.println("D");
T1.start();
}
public void run() {
synchronized (ThreadExample.class) {
for (int i = 0; i < 5; i++) {
try {
System.out.println("Inside run=>"
+ Thread.currentThread().getName());
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
您的问题是,如果两个同步块未锁定在同一监视器上,则它们不是互斥的。
请记住,同步方法锁定在this
监视器上-您的代码等效于:
public void run() {
synchronized(this) {
//your code here
}
}
由于您创建了ThreadExample
两个实例,因此每个实例都有一个不同的this
。
您可以通过在两个线程中使用相同的锁来解决问题,例如:
public void run() {
synchronized(ThreadExample.class) {
//your code here
}
}
甚至更好,只创建一个实例ThreadExample
如指出Quoi 。
您已经创建了ThreadExample
两个Object,因此每个线程都有不同的synchronized
方法。
创建单个对象并将引用传递给线程,您将看到同步的效果。
ThreadExample thex = new ThreadExample();
Thread T=new Thread(thex);
Thread T1=new Thread(thex);
这里两个线程将使用相同的synchronized
方法。
嗯,您正在同步每个线程的run方法。 Thread1不会尝试运行Thread2的run方法,反之亦然。 这就是为什么它实际上与根本不同步的原因相同。
您正在创建该类的两个实例,并且正在类上进行同步,因此它们将独立运行,因为没有通用锁。 他们将继续独立运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.