-1

在下面的代码中,如果我同步方法,它不会对输出产生影响bar- 我做错了什么?我相信同步“bar”会使“ThraOne”被打印10次,然后只打印“ThreadTwo”,但事实并非如此。我得到的输出如下:


我是测试线程:Thread OneOneOneOne
我是测试线程:Thread OneOneOneOne
我是测试线程:Thread OneOneOneOne
我是测试线程:Thread OneOneOneOne
我现在主要
我是测试线程:Thread OneOneOneOne
我是测试线程:线程二
我是测试线程:线程二
我是测试线程:Thread OneOneOneOne
我是测试线程:线程二
我是测试线程:Thread OneOneOneOne
我是测试线程:线程二
我是测试线程:Thread OneOneOneOne
我是测试线程:线程二
我是测试线程:Thread OneOneOneOne
我是测试线程:线程二
我是测试线程:Thread OneOneOneOne
我是测试线程:线程二
我是测试线程:线程二
我是测试线程:线程二
我是测试线程:线程二
我现在主要

等等。这是我的代码:

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();
            }
        }
    }
}
4

3 回答 3

3

您有两个. ThreadTest它们彼此无关;你打电话的不一样bar()

如果您改为这样做:

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

然后两个线程共享一个实例,ThreadTest并且一次只有一个线程能够bar()在该单个实例上调用。

于 2013-02-24T05:51:09.397 回答
2

将方法声明为 synchronized不会产生您期望的效果。每个线程都在自己的 实例上同步ThreadTest,因此调用不会交互。您需要在共享对象上同步一个线程以阻止另一个线程。例如:

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();
                }
            }
        }
    }
}
于 2013-02-24T05:52:31.550 回答
0

您正在同步的方法仅由一个线程访问,因为它们是实例方法,因此每个线程都在调用它自己的bar 方法。

也许您想将 bar 方法声明为static.

于 2013-02-24T05:52:53.200 回答