不同的线程在不同的对象上同步

时间:2017-04-13 08:25:07

标签: java multithreading concurrency monitors

请查看此代码

public class Test extends Thread {
    int i;
    public Test(int i) {this.i = i;}

    void simpleBlock() throws InterruptedException {
        System.out.println(i + " this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.");
        synchronized(this) {wait();}
    }

    public void run() {
        try {simpleBlock();} catch (InterruptedException e) {}
    }
}

这是由创建和启动线程的Main类实现的

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Test[] t = new Test[20];
        for (int i=0; i<20; i++) {
            t[i] = new Test(i);
            t[i].start();
        }
    }
}

这将打印以下输出

0 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
6 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
4 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
3 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
5 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
2 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
1 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
14 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
7 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
13 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
12 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
10 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
11 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
9 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
8 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
18 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
19 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
17 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
16 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
15 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.

由于SimpleBlock()未同步,我期待打印件随机切割。至少,那次我跑了一段时间的另一次同步测试发生了什么,除了我使用信号量(或缺少信号量)的时候。

那么为什么每个Thread都以这样一个有条不紊的方式打印完整的字符串?

这导致我接下来的询问。

让我们说simpleBlock完全同步,输出与上面相同。所以,

    synchronized void simpleBlock() throws InterruptedException {
        System.out.println(i + " this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.");
        wait();
    }

您可能已经知道,这相当于

    void simpleBlock() throws InterruptedException {
        synchronized(this) {
            System.out.println(i + " this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.");
            this.wait();
        }
    }

我假设因为在上面的Main类中创建了20个线程,所以没有两个线程在共享对象上同步,因为每个线程都是它自己的唯一对象,因此,同步方案会有效失败吗?

换句话说,创建多个线程是一个坏主意,每个线程都在自身同步?

1 个答案:

答案 0 :(得分:4)

class Program { class MyClass { public string MyProperty => "Foo"; } static LambdaExpression GetExpression(Expression<Func<MyClass, object>> expr) { return expr; } static void Main(string[] args) { var e1 = GetExpression(t => t.MyProperty); var e2 = Expression.Lambda<Func<object, object>>(e1, e1.Parameters); object myClass = new MyClass(); string s1 = (string)e1.Compile().DynamicInvoke(myClass); object s2 = e2.Compile().Invoke(myClass); } } PrintStream.println所以即使你有很多线程,你的输出也是相对有序的。

来自消息来源

synchronized