简体   繁体   English

简单线程同步问题

[英]Simple Thread Synchronization Issue

In below code, it doesn't make a difference in output if I synchronize the bar method or not - what am I doing wrong? 在下面的代码中,无论是否同步bar方法,输出都不会有所不同-我在做什么错? I believe that synchronizing "bar" will make "ThreaOne" to be printed 10 times and then only printing "ThreadTwo" will start, but it is not the case. 我相信,同步“ bar”将使“ ThreaOne”被打印10次,然后仅开始打印“ ThreadTwo”,但事实并非如此。 The ouput I get is as follows: 我得到的输出如下:


I am Test thread:Thread OneOneOneOne
I am Test thread:Thread OneOneOneOne
I am Test thread:Thread OneOneOneOne
I am Test thread:Thread OneOneOneOne
I am in main now
I am Test thread:Thread OneOneOneOne
I am Test thread:Thread Two
I am Test thread:Thread Two
I am Test thread:Thread OneOneOneOne
I am Test thread:Thread Two
I am Test thread:Thread OneOneOneOne
I am Test thread:Thread Two
I am Test thread:Thread OneOneOneOne
I am Test thread:Thread Two
I am Test thread:Thread OneOneOneOne
I am Test thread:Thread Two
I am Test thread:Thread OneOneOneOne
I am Test thread:Thread Two
I am Test thread:Thread Two
I am Test thread:Thread Two
I am Test thread:Thread Two
I am in main now

and so on. 等等。 Here is my code: 这是我的代码:

package com.rahul;

class ThreadTest implements Runnable{
    @Override
    public void run() {
        bar();
    }
    public synchronized void bar() {
        for(int i=0;i<10;i++){
            System.out.println("I am Test thread:"+Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

public class Test{
    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadTest(),"Thread OneOneOneOne");
        Thread t2 = new Thread(new ThreadTest(),"Thread Two");
        t1.start();
        try{
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        t2.start();
        while(true){
            System.out.println("I am in main now");
            try {
                t2.join();
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

You have two instances of ThreadTest . 您有ThreadTest 两个实例 They have nothing to do with each other; 他们彼此无关。 you're not calling the same bar() 您没有调用相同的bar()

If you do this instead: 如果您改为这样做:

ThreadTest tt = new ThreadTest();
Thread t1 = new Thread(tt,"Thread OneOneOneOne");
Thread t2 = new Thread(tt,"Thread Two");

Then the two threads are sharing an instance of ThreadTest and only one thread will be able to call bar() at a time on that single instance. 然后,两个线程共享一个ThreadTest实例,并且只有一个线程一次可以在单个实例上调用bar()

Declaring the method to be synchronized will not have the effect you expect. 声明要synchronized的方法不会达到您期望的效果。 Each thread is synchronized on its own instance of ThreadTest , so the calls do not interact. 每个线程都在其自己的ThreadTest实例上同步,因此调用不会交互。 You need to synchronized on a shared object for one thread to block another. 您需要在一个共享对象上同步一个线程才能阻止另一个线程。 For instance: 例如:

class ThreadTest implements Runnable{
    private static Object LOCK_OBJECT = new Object();
    @Override
    public void run() {
        bar();
    }
    public void bar() {
        synchronized (LOCK_OBJECT) {
            for(int i=0;i<10;i++){
                System.out.println("I am Test thread:"+Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

The method you're synchronizing is being accessed by only one thread, since they are instance methods, so each thread is calling it's own bar method. 您正在同步的方法仅由一个线程访问,因为它们是实例方法,因此每个线程都在调用它自己的 bar方法。

Maybe you want to declare the bar method as static . 也许您想将bar方法声明为static

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

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