首页 > 解决方案 > Java多线程错误共享问题

问题描述


class PersonValue {
    volatile public int valueA;
    @Contended
    volatile public int valueB;
}

class Person extends Thread {

    public final static long ITERATIONS = 500L * 1000L * 1000L ;
    public static volatile PersonValue personValue = new PersonValue();
    int index = 0;
    public Person(int index) {
        this.index = index;
    }

    @Override
    public void run() {
        long i = ITERATIONS;
        while (--i > 0) {
            if (index == 0) {
                personValue.valueA = 3;
            } else {
                personValue.valueB = 3;
            }
        }
    }
}

public class TestContend {

    public static void main(String[] args) throws InterruptedException {
        long start = System.currentTimeMillis();

        Person person = new Person(0);
        Person person1 = new Person(1);


        person.start();
        person1.start();

        person.join();
        person1.join();

        long end = System.currentTimeMillis();
        System.out.println("Duration " + TimeUnit.MILLISECONDS.toSeconds(end - start));
    }
}

输出:</p>

Duration 3

当我在中注释@Contended代码时PersonValue,输​​出: Duration 11

上面的输出符合我的预期,但是我修改了代码如下:


class Person extends Thread {

    public final static long ITERATIONS = 500L * 1000L * 1000L ;

    public volatile static int personValuesA = 3;
    public volatile static int personValuesB = 1;

    int index = 0;

    public Person(int index) {
        this.index = index;
    }

    @Override
    public void run() {
        long i = ITERATIONS;
        while (--i > 0) {
            if (index == 0) {
                personValuesA = 3;
            } else {
                personValuesB = 3;
            }
        }
    }
}

public class TestContend {

    public static void main(String[] args) throws InterruptedException {
        long start = System.currentTimeMillis();

        Person person = new Person(0);
        Person person1 = new Person(1);


        person.start();
        person1.start();

        person.join();
        person1.join();

        long end = System.currentTimeMillis();
        System.out.println("Duration" + TimeUnit.MILLISECONDS.toSeconds(end - start));
    }
}

输出:

Duration 12

@Contended然后我在中添加了注释personValuesB

class Person extends Thread {
    //...

    public volatile static int personValuesA = 3;
    @Contended
    public volatile static int personValuesB = 1;
}

并输出: Duration 12

两个程序同时运行。为什么?

我的问题:

  1. 为什么添加@Contended注解后运行时间一样?</li>

标签: javamultithreadingthread-safety

解决方案


@Contended不适用于静态字段,仅适用于实例字段。


推荐阅读