简体   繁体   English

同步两个线程不同步

[英]Synchronized two threads not working synchronized

consider the following code: 考虑以下代码:

public class Main {

    public static void main(String[] args){
        MyObject obj = new MyObject();
        Thread1 t1 = new Thread1(100,'#',obj);
        Thread1 t2 = new Thread1(100,'*',obj);

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

public class Thread1 extends Thread {

    int myNum;
    char myChar;
    MyObject myObj;

    public Thread1(int num, char c, MyObject obj){
        myNum = num;
        myChar = c;
        myObj = obj;
    }

    public synchronized void run(){
        for(int i = 1; i<myNum; i++){
            if((i%10)==0)
                System.out.println("");
            System.out.print(myChar);
        }
    }

}

The class MyObject is empty class without anything spacial. MyObject类是没有任何空格的空类。 My question is, why the synchronized is not working and I get printed the '#' and ' ' simultaneously and in random order and not one after the other? 我的问题是,为什么同步不起作用, 而我却 以随机顺序同时而不是一个接一个地 打印'#'和' '?

Synchronization locks the monitor of an object. 同步锁定对象的监视器。 In your case, you are synchronizing against each of the threads objects, that is Thread A locks against Threads A's monitor and Thread B locks against Thread B's monitor. 在您的情况下,您正在针对每个线程对象进行同步,即线程A锁定线程A的监视器,线程B锁定线程B的监视器。 Thus they are not interacting. 因此,它们没有相互作用。

I think that you meant the following for the run() method: 我认为您对run()方法的含义如下:

public void run(){
  synchronized (myObj) {
    for(int i = 1; i<myNum; i++){
        if((i%10)==0)
            System.out.println("");
        System.out.print(myChar);
    }
  }
}

If that was indeed your intended use for myObj, then I would suggest the following change too; 如果确实是myObj的预期用途,那么我也建议进行以下更改; as it will help make the code more readable. 因为它将有助于使代码更具可读性。

Change: 更改:

MyObject myObj;

to: 至:

private final MyObject lock;

EDIT an alternative approach, that does not lock against myObj but instead the Thread1's instance of Class. 编辑一种替代方法,该方法不锁定myObj,而是锁定Thread1的Class实例。

public void run(){
    doJob();
}

private static synchronized void doJob() {
    for(int i = 1; i<myNum; i++){
        if((i%10)==0)
            System.out.println("");
        System.out.print(myChar);
    }
}

You can try to put thread.join() , wait for first thread in execution finished to start next one 您可以尝试放置thread.join() ,等待执行中的第一个线程完成以开始下一个线程

public class hilos {
    public static void main(String[] args) throws InterruptedException{

        MyObject obj = new MyObject();
        Thread1 t1 = new Thread1(50,'#',obj);
        Thread1 t2 = new Thread1(50,'*',obj);

        Thread[] threads = {t1, t2}; 


        start(threads);


    }


    public synchronized static void start(Thread[] threads) throws InterruptedException{

        synchronized(threads){
            for(int i=0; i < threads.length; i++)   {
                threads[i].start();
                threads[i].join();
            }
        }

    }
}

OUTPUT: OUTPUT:

#########
##########
##########
##########
##########*********
**********
**********
**********
**********

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM