我可以在run方法中为Java线程保留一个计数器吗?

我可以在run方法中为Java线程保留一个计数器吗?,java,multithreading,Java,Multithreading,我有一个类变量sum。每次启动一个新线程时,我都希望总和递增。似乎run只被调用了一次,我找不到更好的信息来告诉我更多关于它的信息。有没有一种方法可以用锁来实现这一点?下面是一些简单的代码: public class MyClass implements Runnable{ static int sum = 0; public static void main(String[] args) throws InterruptedException { for(int

我有一个类变量sum。每次启动一个新线程时,我都希望总和递增。似乎run只被调用了一次,我找不到更好的信息来告诉我更多关于它的信息。有没有一种方法可以用锁来实现这一点?下面是一些简单的代码:

public class MyClass implements Runnable{
    static int sum = 0;
    public static void main(String[] args) throws InterruptedException {
        for(int i = 0; i < 5; ++i){
            Thread t = new Thread(new MyClass());
            t.start();
            t = null;
        }
    }
    @Override
        public synchronized void run() {
        ++sum;
        System.out.println(sum);
    }
}
公共类MyClass实现可运行{
静态整数和=0;
公共静态void main(字符串[]args)引发InterruptedException{
对于(int i=0;i<5;++i){
线程t=新线程(新MyClass());
t、 start();
t=零;
}
}
@凌驾
公共同步的无效运行(){
++总和;
系统输出打印项数(总和);
}
}

因为sum是实例变量,例如
MyClass
有一个变量
sum
,初始值为
0
。将
和标记为static,以便在类级别使用它

public class MyClass implements Runnable{
    static int sum = 0;
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 5; ++i) {
            Thread t = new Thread(new MyClass());
            t.start();
            t = null;
        }
    }

    public void run() {
      synchronized (this) {
        sum++;
       System.out.println(sum);
   }
 }
}

在静态变量中保持可变状态是一种不好的做法,但这是解决此问题的方法:

public class MyClass implements Runnable {

    static AtomicInteger counter = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 5; ++i) {
            Thread t = new Thread(new MyClass());
            t.start();
            t = null;
        }
    }

    @Override
    public void run() {
        int sum = counter.incrementAndGet();
        System.out.println(sum);
    }
}
公共类MyClass实现可运行{
静态AtomicInteger计数器=新的AtomicInteger(0);
公共静态void main(字符串[]args)引发InterruptedException{
对于(int i=0;i<5;++i){
线程t=新线程(新MyClass());
t、 start();
t=零;
}
}
@凌驾
公开募捐{
int sum=counter.incrementAndGet();
系统输出打印项数(总和);
}
}

MyClass的每个对象都有自己的
sum
值。您应该先将
sum
设置为static。然后你必须注意同步/线程安全我让sum是静态的,然后我同步运行。它现在打印数字1到5,暂停,然后打印5行1,删除了之前的1到5…抱歉,但这仍然不起作用。它是擦除1到5,然后打印1。还有,为什么要注释掉t=null?从长远来看,这不会导致内存泄漏吗?请确保已将总和标记为静态。它对我有效。@ACHYUTHAPAILI此代码根本不是线程安全的。你的答案根本不起作用。我想我已经解决了:
public类MyClass实现了可运行的{static int sum=0;
public static void main(String[]args)抛出中断异常{``for(int I=0;I<5;++I){`Thread t=new Thread(new MyClass());`t.start();`t=null;`}System.exit(0);`
}
>sum++;`System.out.println(sum);`
}
>“//很抱歉看起来很乱,CTRL K在注释中不起作用,我不知道你是怎么做的…@Goku仍然不是线程安全的。
I++
++I
不是原子运算符,因此不是线程安全的。你需要某种锁(通过
同步的隐式锁或显式锁)或者像
AtomicInteger
这样的特殊类型。仍然不完全是OP想要的。加法是线程安全的,打印不是。OP说“每次我启动一个新线程,我都希望总和递增。”,所以这正是他想要的。打印似乎是他调试工作的一个附带部分。哦…忽略我的评论,监督
总和
=)
public class MyClass implements Runnable {

    static AtomicInteger counter = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 5; ++i) {
            Thread t = new Thread(new MyClass());
            t.start();
            t = null;
        }
    }

    @Override
    public void run() {
        int sum = counter.incrementAndGet();
        System.out.println(sum);
    }
}