Java:在多个线程之间共享变量

标签 java multithreading synchronization atomic

背景:我正在并行运行自动化测试。多个浏览器以相同数量的线程启动,即 1 个浏览器是 1 个线程,在 pom.xml 中使用 fork 。

以下插件位于 pom.xml创建相同数量的Parallel**IT.class作为线程(fork)计数。
所有这些类都是同时并行执行的。所以,似乎每当我创建 volatile variable 时或AtomicInteger每个线程都会创建自己的变量,因此跨多个线程共享变量的概念不起作用。

                <plugin>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <version>${maven.failsafe.plugin}</version>
                        <configuration>
                            <systemPropertyVariables>
                                <webdriver.base.url>${webdriver.base.url}</webdriver.base.url>
                                                                </systemPropertyVariables>
                            <argLine>
                                -javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
                            </argLine>
                            <forkCount>5</forkCount>
                            <reuseForks>true</reuseForks>
                            <includes>
                                <include>**/Parallel*IT.class</include>
                            </includes>
                            <perCoreThreadCount>true</perCoreThreadCount>
                            <properties>
                                <property>
                                    <name>listener</name>
            <value>ru.yandex.qatools.allure.junit.AllureRunListener</value>
                                </property>
                            </properties>
                        </configuration>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>


我只希望 1 个线程访问“准备测试数据”功能并设置 flagfalse ,当其他线程看到flag时如false他们不会尝试准备测试数据。

我正在学习教程 https://www.youtube.com/watch?v=WH5UvQJizH0实现synchronization使用volatile多变的。也许我犯了一些错误,但所有线程都在打印 System.out.println("Preparing test data");

尝试1: volatile 和同步

volatile boolean flag = false;

    public synchronized void setFlagTofalse(){
        System.out.println("Inside sync block");
          this.flag = true;
    }
    // works before class only once
    private EventHandler<TestRunStarted> prepareTestData = event -> {
            if(flag==false) {
                System.out.println("Preparing test data");              
                setFlagTofalse();
            }
    };

尝试 2:原子和同步

AtomicInteger flag = new AtomicInteger(0);

    private EventHandler<TestRunStarted> prepareTestData = event -> {
        if(flag.get()==0) {
            System.out.println("Preparing test data");
            value.incrementAndGet();
        }

最佳答案

如果我是你,我会在访问标志变量时实现互斥锁。因此,在读取标志的值或更改其值之前,线程必须获取锁。这样,他们就不会同时读取它,也不会在读取旧值时写入新值,等等。

编辑:更多说明

@paul 解释一下锁的作用:它基本上是一个可以被线程抛掷的球。因此,如果你和一群人围坐一圈,并且你有球,那么就轮到你谈论“X”了。然后,一旦你说完,你就把球放在圆圈的中间,它会一直留在那里,直到同一个人或其他人再次想要球并拿走它,或者等到它可用,然后可以谈论“X”。在您的情况下,线程必须拥有锁才能更改或读取变量标志,因此您要做的是:

Mutex lock = new Mutex();
lock.aquire();
if ( flag == something ){
    //do something
}
mutex.release()

或者如果您要更改标志。

lock.aquire();
flag = something;
lock.release();

正如您所看到的,锁是在线程之间共享的。因此它是在管理线程的类中创建的,并传递给线程中启动的可运行对象或方法。

所以:

Mutex lock = new Mutex();
Runnable1 r1 = new Runnable1(lock);
Runnable2 r2 = new Runnable2(lock);
//use the lock in the methods of t1 and t2 that use your volitile var
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);

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

//the join wait for completion of the runnable method in your class.
t1.join();
t2.join();

祝你好运:)

关于Java:在多个线程之间共享变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56273532/

相关文章:

java - spring-security 解耦角色和权限

java - 在 Java 中不旋转就阻塞?

mysql - mysql中同步存储过程执行

java - 为什么这个比较返回 false?

java - 使用 PowerMockito 模拟文件

c# - 多线程 .NET 应用程序导致在 64 位四核 Windows Server 上运行的 KERNEL32.dll 中出现应用程序错误

c# - 对同一个对象的多个 WeakReferences 是否总是同步的?

optimization - CUDA:同步线程

.net - ReaderWriterLockSlim : acquiring a read lock after an upgradeable lock doesn't throw LockRecursionException

java - 插入数据时JSP页面错误