如何用rxjava替换使用volatile变量的线程间通信?
我有一个应用程序,通过让一个线程在另一个线程检查的对象上设置一个可变变量,在线程之间进行大量通信。我发现这很容易出错,我想尝试用RxJava替换它,但有些情况下我不知道如何转换 我现在正在努力解决的问题是,我有两个线程,让我们把一个称为控制器,另一个称为测量器。测量员的工作是每100ms记录一些数量。控制器与应用程序的各个部分进行大量对话,并且每隔一段时间,它会告诉测量者改变测量内容。现在,它通过设置一个可变变量来实现这一点,并且测量器循环的每次迭代都会检查该变量,以查看要测量什么 测量器不能与控制器处于同一线程中,因为测量需要时间,控制器不能延迟它正在执行的其他工作 感觉解决方案类似于使控制器成为可观察的对象,每当对测量者的指令需要更新时,它就会发出一个项目,但我能看到的唯一方法是,当接收到事件时,测量者改变其行为,就是让这些事件的订阅者像以前一样设置易失性变量,然后我就什么都没有了如何用rxjava替换使用volatile变量的线程间通信?,java,android,multithreading,rx-java,rx-java2,Java,Android,Multithreading,Rx Java,Rx Java2,我有一个应用程序,通过让一个线程在另一个线程检查的对象上设置一个可变变量,在线程之间进行大量通信。我发现这很容易出错,我想尝试用RxJava替换它,但有些情况下我不知道如何转换 我现在正在努力解决的问题是,我有两个线程,让我们把一个称为控制器,另一个称为测量器。测量员的工作是每100ms记录一些数量。控制器与应用程序的各个部分进行大量对话,并且每隔一段时间,它会告诉测量者改变测量内容。现在,它通过设置一个可变变量来实现这一点,并且测量器循环的每次迭代都会检查该变量,以查看要测量什么 测量器不能与
我想知道我是否可以以某种方式获取控制器发出的项目流,并将其转换为一个重复每个项目的流,直到控制器发出不同的项目,然后我可以在测量器中订阅这些重复的项目,该测量器将在每次收到一个项目时进行测量。这是正确的方法吗?如果是,我如何将控制器发出的项目转换为重复的项目流?我对Rx比较陌生,但我会使用行为主体。您可以使用distinctUntilChanged(),或将其与可观察的计时器组合使用:
public enum Stat { FOO, BAR }
public class Controller
{
private Subject<Stat> statSubject;
public Controller()
{
statSubject = BehaviorSubject.<Stat>create().toSerialized();
}
public Observable<Stat> getStatChange()
{
return statSubject.distinctUntilChanged();
}
public void setStat( Stat stat )
{
statSubject.onNext( stat );
}
}
public class Measurer
{
public Measurer( Controller controller )
{
Observable.timer( 1, TimeUnit.SECONDS, Schedulers.newThread() )
.repeat()
.withLatestFrom(
controller.getStatChange(),
( __, stat ) -> stat ) // ignore the Long emitted by timer
.subscribe( this::measureStat );
}
private void measureStat( Stat stat )
{
switch( stat )
{
case FOO:
measureFoo();
break;
default:
measureBar();
break;
}
}
private void measureBar()
{
System.out.println( "Measuring Bar" );
}
private void measureFoo()
{
System.out.println( "Measuring Foo" );
}
}
@Test
public void testMeasureStats() throws InterruptedException
{
Controller controller = new Controller();
controller.setStat( Stat.BAR );
@SuppressWarnings( "unused" )
Measurer measurer = new Measurer( controller );
Thread.sleep( 5000 );
controller.setStat( Stat.FOO );
Thread.sleep( 5000 );
controller.setStat( Stat.BAR );
Thread.sleep( 5000 );
}
我对Rx比较陌生,但我会使用行为主体。您可以使用distinctUntilChanged(),或将其与可观察的计时器组合使用:
public enum Stat { FOO, BAR }
public class Controller
{
private Subject<Stat> statSubject;
public Controller()
{
statSubject = BehaviorSubject.<Stat>create().toSerialized();
}
public Observable<Stat> getStatChange()
{
return statSubject.distinctUntilChanged();
}
public void setStat( Stat stat )
{
statSubject.onNext( stat );
}
}
public class Measurer
{
public Measurer( Controller controller )
{
Observable.timer( 1, TimeUnit.SECONDS, Schedulers.newThread() )
.repeat()
.withLatestFrom(
controller.getStatChange(),
( __, stat ) -> stat ) // ignore the Long emitted by timer
.subscribe( this::measureStat );
}
private void measureStat( Stat stat )
{
switch( stat )
{
case FOO:
measureFoo();
break;
default:
measureBar();
break;
}
}
private void measureBar()
{
System.out.println( "Measuring Bar" );
}
private void measureFoo()
{
System.out.println( "Measuring Foo" );
}
}
@Test
public void testMeasureStats() throws InterruptedException
{
Controller controller = new Controller();
controller.setStat( Stat.BAR );
@SuppressWarnings( "unused" )
Measurer measurer = new Measurer( controller );
Thread.sleep( 5000 );
controller.setStat( Stat.FOO );
Thread.sleep( 5000 );
controller.setStat( Stat.BAR );
Thread.sleep( 5000 );
}
双方都可以有一个可观察的字段,而不是在其他类中设置字段。。。。事实上,这是一个更强的设计…更强的设计听起来很棒!你能详细解释一下你的意思吗?我不确定测量者有一个可观测值意味着什么,因为没有人想观测它。双方都可以有一个可观测值,而不是在其他类中设置字段。。。。事实上,这是一个更强的设计…更强的设计听起来很棒!你能详细解释一下你的意思吗?我不确定测量者有一个可观察的东西意味着什么,因为没有人想观察它。