不同类中的同步属性



我正在尝试设置 2 个线程,这些线程在另一个类中增加或减少整数。我在同步此属性时遇到了一些问题。

这是我的主要类,我在其中设置了线程和计数器类:

public class Main {
public static void main(String[] arg) {
    Counter c = new Counter(10000000);
    Thread1 t1 = new Thread1(c);
    Runnable2 r2 = new Runnable2(c);
    Thread t2 = new Thread(r2);
    t1.start();
    t2.start();
    System.out.println(t.getNumber());
    }
}

这是我的计数器类:

public class Counter{
private int number;
private static final Object countLock = new Object();
public Counter(int number){
    this.number= number;
}
public void increase(){
    synchronized(countLock){
        number++;
    }
}
public void decrease(){
    synchronized(countLock){
        number--;
    }
}
public int getNumber(){
    return number;
}
}

这是我的 Thread1 类:(可运行的类是相同的,只是使用"实现 Runnable"而不是"扩展线程")

public class Thread1 extends Thread{
private Counter c;
public Thread1(Counter c){
    this.c = c;
}
public void run(){
    for(int i = 0; i < c.getNumber(); i++){
        c.increase();
    }
}
}

但是,我的输出始终是 10000000。即使我同步了这两种方法。有人可以解释发生了什么吗?

在启动t1.join(); t2.join();后添加它们,以便线程在main线程执行 sysout 之前完成其任务。

另一方面,我认为随着c.getNumber()不断增加,线程永远不会从for loop中出来。

我想你想拥有

int number=c.getNumber(); for(int i = 0; i < number; i++) {

而不是

for(int i = 0; i < c.getNumber(); i++) {

当我运行您的代码时,System.out.println(t.getNumber()); 正在任何一个线程启动之前执行。

首先,这实际上应该永远不会结束,因为您在同一循环中增加了for循环中用作上限的值。不确定这是否是所需的行为。

其次,您的System.out.println将(很可能)始终打印Counter中使用的初始值,因为线程没有时间完成其工作。出于测试目的,您可以添加类似 TimeUnit.SECONDS.sleep(10); .对于更复杂的方法,我建议您查看java.util.concurrent.Executorsjava.util.concurrent.ExecutorService(那里有很多示例)。

第三,如果你用java.util.concurrent.atomic.AtomicInteger代替你的Counter int number,你的生活会轻松得多。

最新更新