Java 同步线程方法正在并发执行-为什么?
我有一个关于线程的问题。我有以下线程类和创建2个线程对象Java 同步线程方法正在并发执行-为什么?,java,multithreading,Java,Multithreading,我有一个关于线程的问题。我有以下线程类和创建2个线程对象 public class MyThread extends Thread{ String name=""; public MyThread(String string) { name=string; } @Override public void run() { callMe(); } synchronized priva
public class MyThread extends Thread{
String name="";
public MyThread(String string) {
name=string;
}
@Override
public void run() {
callMe();
}
synchronized private void callMe() {
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(name+" = "+i);
}
}
public static void main(String[] args) {
MyThread a = new MyThread("A");
MyThread b = new MyThread("B");
a.start();
b.start();
}
}
我知道A和B是随机打印的,因为线程调度程序会选择它
但我的问题是:为什么不一个接一个地执行循环?我使用了
synchronized
关键字。每个对象的同步工作。要跨实例同步,您需要一个共享对象进行同步
即
private final static Object globalLock=new Object();
//后来
私有无效callMe(){
已同步(全局锁定){
System.out.println(“已启动”);
对于(inti=1;i,因为两个线程通过两个不同的对象执行
好的,您现在必须已经从其他答案中认识到了。您正在创建两个单独的对象,即a和b。现在,当您调用start方法时,将通过相应的run方法启动一个新线程以执行(单独的不是相同的)对象。同步确实在方法上,但正好有一个线程通过a的callMe方法运行,正好有一个线程通过b的callMe方法运行。因此,您希望输出应该是:
A-1
A-2
A-3
这是不可能的
希望这有助于您的同步
方法有效:
private void callMe() {
synchronized(this) {
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(name+" = "+i);
}
}
}
然后您将得到如下输出:
public final class DemoRunnable implements Runnable {
@Override
public synchronized void run() {
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " = " + i);
}
}
public static void main(String[] args) {
Runnable runnable = new DemoRunnable();
Thread a = new Thread(runnable, "A");
Thread b = new Thread(runnable, "B");
a.start();
b.start();
}
}
Started
A = 1
A = 2
A = 3
A = 4
A = 5
Started
B = 1
B = 2
B = 3
B = 4
B = 5
(当然,这可能是另一种情况。)
我们仍然有两个线程,但它们在同一个对象上调用同步方法(在本例中是ademorunable
),因此其中一个线程必须等待另一个线程完成
有几点:
- 实现
Runnable
通常比扩展线程更可取;它更灵活
- 在
线程
对象上进行同步有其自身的问题,因为线程
类自己做;请尽量避免
- 就我个人而言,无论如何我都不喜欢在
这个
上同步-我通常会有一个类型为Object
的私有final变量来表示一个只有我的代码才知道的监视器…这样我就可以很容易地看到所有可以在上面同步的代码,这就更容易进行推理
您的代码与此代码相同
private void callMe(){
已同步(此){
System.out.println(“已启动”);
对于(inti=1;i-1从我这里-这是一个非常简洁的答案。没有足够的信息来解释问题发生的原因。好吧,好吧,我将详细说明:)globalLock必须是强制静态的。否则它就不能正常工作?使用静态对象(而不是实例对象)的原因因此,每个实例都在同一个对象上同步。我建议将globalLock
声明为显式private
,也声明为final
。因此,在第一个代码段中,它不会保持同步方法
对吗?它将变为同步语句
。第二个代码段是exaSynchronized方法的示例
我说得对吗?@ninappingale:是的,但这种差异实际上是不相关的-一个Synchronized
方法实际上是一个普通方法,带有一个包含方法主体的Synchronized(this)
语句。(例如方法;对于静态方法,它在类
对象上同步。)
Started
A = 1
A = 2
A = 3
A = 4
A = 5
Started
B = 1
B = 2
B = 3
B = 4
B = 5
private void callMe(){
synchronized(this){
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(name+" = "+i);
}
}
}
private void callMe(){
synchronized(MyThread.class){
System.out.println("Started");
for (int i = 1; i <= 5; i++) {
System.out.println(name+" = "+i);
}
}
}