繁体   English   中英

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

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

我是并发的新手,我正在尝试理解同步块:

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

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

我的问题是lock1,它不起作用,当方法开始打印颜色时,它会随机打印它们,所以我认为问题出在同步块中,因为我看了一些关于这个的教程,他们都说锁定对象必须是静态的,所以不会发生干扰,但在这里我没有看到,为什么?

这是打印每个线程颜色的方法:

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

这是线程:

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);

    }

对不起,如果我的英语不好,我不是母语人士,提前致谢

首先,我想现在我明白你的问题了。 您试图在不干扰其他线程的行的情况下打印出您的行。

为了实现这一点,你必须“保护”你的代码部分,它打印出一行,而不是同时从另一个线程打印出另一行。

可以通过同步这些代码行来完成保护。

您当前仅同步该计数器的添加。

您的锁(您锁定的对象,即 new Object() 的唯一实例)是静态的,您无需在代码中更改它,因此它必须有效。

public static Object lock1 = new Object();

您可以将变量设置为 final 以使其不可变,但目前这不是问题。 不过,我会建议这样做。

锁意味着,如果任何其他线程登陆(执行)同一行代码(同步块的开头),它们将不会得到执行,直到阻塞线程放弃它的锁。 只有当他们持有并请求相同的锁时,这才是正确的。 由于您只使用相同的 new Object() 实例,因此您的锁应该没问题。

目前,您的代码已构建为 add() 方法基本上等待,直到其中一个线程正在计数。

如果要更改它以便单独打印行,请尝试像这样同步“行打印块”:

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

并且让计数不同步。

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

这会起作用,但大多数情况下您不想让您的 add() 方法不同步。 它可以从其他线程执行,谁知道呢。 但是对于您的情况,这些更改会有所帮助。

暂无
暂无

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

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