如何用rxjava替换使用volatile变量的线程间通信?

如何用rxjava替换使用volatile变量的线程间通信?,java,android,multithreading,rx-java,rx-java2,Java,Android,Multithreading,Rx Java,Rx Java2,我有一个应用程序,通过让一个线程在另一个线程检查的对象上设置一个可变变量,在线程之间进行大量通信。我发现这很容易出错,我想尝试用RxJava替换它,但有些情况下我不知道如何转换 我现在正在努力解决的问题是,我有两个线程,让我们把一个称为控制器,另一个称为测量器。测量员的工作是每100ms记录一些数量。控制器与应用程序的各个部分进行大量对话,并且每隔一段时间,它会告诉测量者改变测量内容。现在,它通过设置一个可变变量来实现这一点,并且测量器循环的每次迭代都会检查该变量,以查看要测量什么 测量器不能与

我有一个应用程序,通过让一个线程在另一个线程检查的对象上设置一个可变变量,在线程之间进行大量通信。我发现这很容易出错,我想尝试用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 );
    }

双方都可以有一个可观察的字段,而不是在其他类中设置字段。。。。事实上,这是一个更强的设计…更强的设计听起来很棒!你能详细解释一下你的意思吗?我不确定测量者有一个可观测值意味着什么,因为没有人想观测它。双方都可以有一个可观测值,而不是在其他类中设置字段。。。。事实上,这是一个更强的设计…更强的设计听起来很棒!你能详细解释一下你的意思吗?我不确定测量者有一个可观察的东西意味着什么,因为没有人想观察它。