简体   繁体   English

使用静态对象锁时不起作用?

[英]When using static object lock doesn't work?

I'm new at Concurrency, i'm trying to understand synchronized block:我是并发的新手,我正在尝试理解同步块:

public static int count1 = 0;
public static Object lock1 = new Object();

public static void add(){
        synchronized (lock1) {
            count1++;
        }
}

my problem is with lock1, it doesn't work, when the method starts printing the color, it prints them randomly, so i think the problem is in synchronized block, because i watch some tutorials about this, all of them say the lock object must be static so no interference happens, but here i don't see that, Why?我的问题是lock1,它不起作用,当方法开始打印颜色时,它会随机打印它们,所以我认为问题出在同步块中,因为我看了一些关于这个的教程,他们都说锁定对象必须是静态的,所以不会发生干扰,但在这里我没有看到,为什么?

This is the method that prints the color of each thread:这是打印每个线程颜色的方法:

public static void compute(){
        String color = null;
        switch (Thread.currentThread().getName()) {
            case "First Count Down":
                color = TextColors.ANSI_YELLOW;
                break;
            case "Second Count Down":
                color = TextColors.ANSI_MAGENTA;
                break;
        }
        for (int i=0;i<100;i++) {
            System.out.println(color + Thread.currentThread().getName() + "is Running");
            //add();
            add();
        }
    }

and this is the threads :这是线程:

public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                compute();
            }
        });
        t1.setName("First Count Down");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                compute();
            }
        });
        t2.setName("Second Count Down");

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

        try{
            t1.join();
            t2.join();

        }catch (InterruptedException io){
            io.printStackTrace();

        }

        System.out.println("Count1 = " + count1 + " Count2 = " + count2);

    }

Sorry if my English is bad, i'm not a native speaker, thanks in advance对不起,如果我的英语不好,我不是母语人士,提前致谢

First of all, I think now I understand your question.首先,我想现在我明白你的问题了。 You're trying to print out your lines without interfering with the lines of the other threads.您试图在不干扰其他线程的行的情况下打印出您的行。

To achieve this, you have to "protect" the part of your code, which prints out one line, not to get printed out another line at the same time from another thread.为了实现这一点,你必须“保护”你的代码部分,它打印出一行,而不是同时从另一个线程打印出另一行。

The protection can be done by synchronizing those lines of code.可以通过同步这些代码行来完成保护。

You are currently synchronizing only the addition to that counter.您当前仅同步该计数器的添加。

Your lock (the object you're locking on, the one and only instance of that new Object()) is static and you do not change it in your code, so it must work.您的锁(您锁定的对象,即 new Object() 的唯一实例)是静态的,您无需在代码中更改它,因此它必须有效。

public static Object lock1 = new Object();

You could make the variable to final to get immutable, but currently that's not the problem.您可以将变量设置为 final 以使其不可变,但目前这不是问题。 I would recommend that though.不过,我会建议这样做。

The lock means, that if any other thread is landing in (executing) the same line of code (the beginning of the synchronized block), they won't get execution until the blocking thread is giving up its lock.锁意味着,如果任何其他线程登陆(执行)同一行代码(同步块的开头),它们将不会得到执行,直到阻塞线程放弃它的锁。 This is only true, if they holding and asking for the very same lock.只有当他们持有并请求相同的锁时,这才是正确的。 And as you're only using the very same new Object() instance, your lock should be okay.由于您只使用相同的 new Object() 实例,因此您的锁应该没问题。

Currently your code is built up that the add() method basically waits until one of the threads is counting up one.目前,您的代码已构建为 add() 方法基本上等待,直到其中一个线程正在计数。

If you want to change it so that you're getting separately printed out lines, try to synchronize the "line printing block" like this:如果要更改它以便单独打印行,请尝试像这样同步“行打印块”:

    synchronized (lock1) {
        System.out.println(color + Thread.currentThread().getName() + "is Running");
        add();
    }

And let the counting not be synchronized.并且让计数不同步。

private static void add(){
    count1++;
}

This would work but mostly you don't want to let your add() method unsynchronized.这会起作用,但大多数情况下您不想让您的 add() 方法不同步。 It could be executed from other threads, who knows.它可以从其他线程执行,谁知道呢。 But for your case, those changes would help.但是对于您的情况,这些更改会有所帮助。

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

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