当前位置: 首页 > 知识库问答 >
问题:

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

董翰墨
2023-03-14

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

pom.xml中的下面插件创建了与线程(fork)计数相等数量的并行**IT.class
所有这些类都同时并行执行。因此,似乎每当我创建易失性变量原子整数时,每个线程都会创建自己的这些,因此跨多个线程共享变量的概念是不起作用的。

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


我只想让一个线程访问“准备测试数据”函数,并将<code>标志

我正在按照教程https://www.youtube.com/watch?v=WH5UvQJizH0使用易失性变量实现同步。也许我犯了一些错误,但所有线程都在打印System.out.println(“准备测试数据”);

尝试 1:易失性和同步

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

共有3个答案

汪高岑
2023-03-14

您同步了错误的方法。你可以试试这样的方法:

volatile boolean flag = false;

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

private synchronized void prepareData() {
    if(!flag) {
        System.out.println("Preparing test data");
        setFlagTofalse();
    }
    //prepare data here
}
汪信鸥
2023-03-14

如果你做了一个测试(flag.get()==0)和一个操作,你有两个同步这两个东西。只需将你的整个准备测试数据方法标记为同步?

严信瑞
2023-03-14

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

编辑:更多解释

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

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

或者如果你正在改变旗帜。

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

如您所见,锁是在线程间共享的。所以它是在管理线程的类中创建的,并被传递给线程中启动的Runnable对象或方法

所以:

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

祝你好运:)

 类似资料:
  • 问题内容: 我有两个线程。可以调用修改变量的类的update方法。另一个调用读取该变量的类的update方法。只有一个线程写入,一个(或多个)线程读取该变量。由于我是多线程技术的新手,我需要在并发方面做什么? 谢谢, 问题答案: 如果有且仅有一个写线程,你可以逃脱使得它。否则,请查看答案。 仅在只有一个写线程的情况下才起作用,因为只有一个写线程,因此它始终具有的正确值。

  • 问题内容: 我想像这样在多个线程之间共享一个变量: 我想在主线程和帮助线程之间共享,这是我创建的两个不同的Java类。有什么办法吗?谢谢! 问题答案: 二者并可以参照包含该变量的类。 然后,可以使该变量为 volatile ,这意味着 对该变量的更改在两个线程中立即可见。 有关更多信息,请参见本文。 易变变量 共享已同步的可见性功能,但不共享原子性功能。这意味着线程将自动 查看volatile变量

  • 问题内容: 我们遇到了适用于多线程的方案。 在主线程中,执行一些逻辑操作并更新数据库,在某种程度上,它将调用另一个服务来更新数据库,该服务在另一个线程中运行。 我们希望两个线程共享同一个事务,这意味着任何一个线程中的任何一个操作都将失败,那么另一个线程中的该操作也将被回滚。 但是工作了几天,我发现一些帖子说JTA不支持多线程。当前我们使用Bitronix作为JTA提供者,有没有人知道Bitroni

  • Python 3.1.2 我对多处理产生的两个线程之间的变量共享有问题。过程这是一个简单的bool变量,它应该决定线程是应该运行还是应该停止执行。下面是三种情况下显示的简化代码(但使用与我的原始代码相同的机制): 主要用于Thread加工。Thread类型和自紧度。正在运行布尔类型[工作正常] 我想了解的是为什么它是这样工作的,而不是另一种。(即,为什么第2点没有像我认为的那样起作用)。 测试是从

  • 问题内容: 我的高级Java课堂上有关线程的老师说了一些我不确定的东西。以下代码不一定会更新ready变量。根据他的说法,这两个线程不一定共享静态变量,特别是在每个线程(主线程与)在其自己的处理器上运行并且因此不共享相同的寄存器/缓存/等和一个CPU的情况下。不会更新其他。 从本质上讲,他说有可能在主线程中进行更新,而不是在中进行更新,因此将无限循环。 他还声称该程序可以打印或打印。我了解如何打印

  • 问题内容: 我正在使用“线程”模块在Python中进行项目。 如何创建一个全局变量(在我的情况下,我需要为True或False),以便项目中的所有线程(大约4-6)都可以访问? 问题答案: 我们可以在线程类外部定义变量,并在类的方法内部全局声明它。 请参见下面的简单示例,它交替打印AB。两个变量和在两个线程和之间共享。打印,然后设置为30。打印,因为已在中进行了修改。然后设置为20,再次用于中。这