java中的synchronized关键字
我从扩展线程类的类a创建了两个线程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
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