同步无助于实现互斥

时间:2014-05-31 14:22:48

标签: java multithreading thread-safety

C类:

class C extends Thread
{
    public static int cr;

    C(int n) 
    {
        cr = n;
    }

    public void run()
    {
        go();
    }

    synchronized void go()
    {
        for (int i = 0; i < 10000; i++)
        {
            cr++;
        }
    }
}

班级启动

class Launch
{
    public static void main(String args[]) throws InterruptedException
    {
        C[] c = new C[10];

        for (int i = 0; i < 10; i++)
        {
            c[i] = new C(0);
        }

        for (int i = 0; i < 10; i++)
        {
            c[i].start();
        }

        System.out.println(C.spaces);
    }
}

它不会给我100,000,而是数字低于100k。为什么?我使方法go()同步,所以一次只能由一个线程使用..?我错过了什么?

3 个答案:

答案 0 :(得分:1)

synchronized void go(){...}表示它在当前实例上同步(在this上)。由于此方法属于您的自定义Thread类,并且您正在创建10个线程,因此存在10个不同的this引用。

这是首选不扩展Thread类的原因之一,而是实现Runnable接口并将此接口的实例传递给任意数量的线程。

另一个问题是您正在打印已编辑的值而不等待线程完成。

您需要创建一个实例来保存您想要更改的值,并仅从 一个实例 调用同步方法,因为默认情况下提到{{1}在synchronized void method(调用此方法的当前对象)上同步。

this

答案 1 :(得分:0)

 c[i] = new C(0);

您每次都在创建新的c实例

 synchronized void go()
{
    for (int i = 0; i < 10000; i++)
    {
        cr++;
    }
}

你总是会得到不到10000的数字我不知道为什么你期待100,000

这是一个错误的错误我&lt; 10000你应该使用100,000?

回答你的上一个问题

I made method go() synchronized, so it should be used by only one thread at a time..?

如果一次只有一个线程,则不需要同步(多线程概念)。

答案 2 :(得分:0)

它不会给我100,000,而是数字低于100k。为什么?

  

每件事情都运行正常,但main线程没有等待其他线程完成计算,因此main线程中的输出是随机的。

使用Thread#join()以便主线程在执行主线程的最后一行之前等待所有其他线程死掉。

for (int i = 0; i < 10; i++) {
    c[i].start();
    c[i].join(); // Waits for this thread to die
}

System.out.println(C.cr); // output 100000

值得一读How do I pause main() until all other threads have died?