java中的synchronized关键字

java中的synchronized关键字,java,multithreading,synchronization,Java,Multithreading,Synchronization,我从扩展线程类的类a创建了两个线程a1,a2。类A声明两个构造函数并运行同步的方法。当我以这种形式编写代码时,虽然run方法声明为synchronized,并且我得到的结果如下,但两个线程有时同时启动 0 0 1 1 2 3 4 5 6 7 2 8 3 9 4 10 5 11 6 12 7 8 9 10 11 12 代码: 同步方法runwork和两个线程不会同时启动总是给出结果 0 1 2 3 4 5 6 7 8 9 10 11 12 0 1 2 3 4 5 6 7 8 9 10 11 1

我从扩展线程类的类a创建了两个线程
a1
a2
。类A声明两个构造函数并运行同步的方法。当我以这种形式编写代码时,虽然
run
方法声明为synchronized,并且我得到的结果如下,但两个线程有时同时启动

0 0 1 1 2 3 4 5 6 7 2 8 3 9 4 10 5 11 6 12 7 8 9 10 11 12 
代码:

同步方法
run
work和两个线程不会同时启动总是给出结果

0 1 2 3 4 5 6 7 8 9 10 11 12 0 1 2 3 4 5 6 7 8 9 10 11 12 

我的问题:为什么synchronized关键字在我从类a创建两个线程时不起作用(尽管我定义了两个构造函数),而在我从Thraed类创建两个线程时不起作用?

除非使用像
信号灯这样的同步器,否则无法确保线程同时启动,
countdownlock
CyclicBarrier

synchronized
关键字本身用于保护相同的对象(方法或代码块)不受并发访问。在您的代码中,
同步
是无用的。

当您通过调用
start()
运行线程时,它会在某个点调用其
run()
方法,该方法在
线程
类中如下所示:

public void run() {
    if (target != null) {
        target.run();
    }
}
此代码负责执行传入新线程(可运行目标)
构造函数的
Runnable target
对象的
run
方法中的代码

但是您在
A
类中重写了
Thread\run()
。所以现在
start()
方法调用
A#run
(因为多态性),这意味着它从不调用
target.run()
(在您的例子中-
t.run()
,因为
t
作为
A
线程目标传递)。
现在,即使
run
方法是
synchronized
,因为每个线程在单独的实例(线程对象本身)上调用它,也不会发生同步,因为线程没有使用公共锁/监视器

只有当一个线程能够在另一个线程启动之前完成全部工作时,才能得到正确的结果


为了避免这些令人困惑的问题(以及许多其他问题)根本不要扩展线程。创建实现Runnable的类并将其传递给
线程
实例


Runnable
视为任务,将
Thread
视为应该执行该任务的工作者。你的工作是描述员工应该做什么(拿着这个,放在那里),而不是如何(弯曲膝盖,抓住那个…。

下面是处理问题的修改代码

public class RunnableDemo {  
    public static void main(String[] args) {    

        Object lock = new Object();
        Thread t1 = new Thread (new MyRunnable(lock));      
        Thread t2 = new Thread (new MyRunnable(lock));      

        t1.start();
        t2.start();
    }    
}

class MyRunnable implements Runnable {
    Object lock = new Object();
    public MyRunnable(Object lock){
        this.lock = lock;
    }

    @Override
    public void run () {  
        synchronized(lock){
            for (int i = 0; i <13; i++) {
                System.out.print(i+" ");             
            }  
        }           
    }
}

我刚刚展示了基本的锁定机制。有关多线程的高级版本,请参阅教程

在第一种情况下,您如何看待线程同时启动?你看到混合输出了吗?您能给我们看一下输出吗?我可以向您保证,
synchronized
确实工作正常。您正在
线程上进行同步
对象本身,这实际上有点毫无意义。我的朋友synchronized总是正常工作。现在你的错误是理解这里的线程a1=新线程(t);螺纹a2=新螺纹(t);small description=您正在创建两个具有两个不同锁的不同对象,对吗?那么为什么一个线程会等待你得到这个??两个线程具有不同的锁。知道了?
public void run() {
    if (target != null) {
        target.run();
    }
}
public class RunnableDemo {  
    public static void main(String[] args) {    

        Object lock = new Object();
        Thread t1 = new Thread (new MyRunnable(lock));      
        Thread t2 = new Thread (new MyRunnable(lock));      

        t1.start();
        t2.start();
    }    
}

class MyRunnable implements Runnable {
    Object lock = new Object();
    public MyRunnable(Object lock){
        this.lock = lock;
    }

    @Override
    public void run () {  
        synchronized(lock){
            for (int i = 0; i <13; i++) {
                System.out.print(i+" ");             
            }  
        }           
    }
}
0 1 2 3 4 5 6 7 8 9 10 11 12 0 1 2 3 4 5 6 7 8 9 10 11 12