首页 \ 问答 \ Java - 使用nio的ReadObject(Java - ReadObject with nio)

Java - 使用nio的ReadObject(Java - ReadObject with nio)

在传统的阻塞线程服务器中,我会做这样的事情

class ServerSideThread {

    ObjectInputStream in;
    ObjectOutputStream out;
    Engine engine;

    public ServerSideThread(Socket socket, Engine engine) {
        in = new ObjectInputStream(socket.getInputStream());
        out = new ObjectOutputStream(socket.getOutputStream());
        this.engine = engine;
    }

    public void sendMessage(Message m) {
        out.writeObject(m);
    }

    public void run() {
        while(true) {
            Message m = (Message)in.readObject();
            engine.queueMessage(m,this); // give the engine a message with this as a callback
        }
    }
}

现在,可以预期该对象非常大。 在我的nio循环中,我不能简单地等待对象通过,所有其他连接(具有更小的工作负载)将等待我。

在告诉我的nio频道之前,我怎么才能通知连接有整个对象?


In a traditional blocking-thread server, I would do something like this

class ServerSideThread {

    ObjectInputStream in;
    ObjectOutputStream out;
    Engine engine;

    public ServerSideThread(Socket socket, Engine engine) {
        in = new ObjectInputStream(socket.getInputStream());
        out = new ObjectOutputStream(socket.getOutputStream());
        this.engine = engine;
    }

    public void sendMessage(Message m) {
        out.writeObject(m);
    }

    public void run() {
        while(true) {
            Message m = (Message)in.readObject();
            engine.queueMessage(m,this); // give the engine a message with this as a callback
        }
    }
}

Now, the object can be expected to be quite large. In my nio loop, I can't simply wait for the object to come through, all my other connections (with much smaller workloads) will be waiting on me.

How can I only get notified that a connection has the entire object before it tells my nio channel it's ready?


原文:https://stackoverflow.com/questions/5862971
更新时间:2023-06-26 07:06

最满意答案

这是因为你正在开始所有的计时器,而不是像你想的那样一个接一个。 有几种方法可以做到这一点

  1. 只需使用一个CountDownTimer并根据经过多少时间更新onTick方法中的数据

    fun WordChanger(num: Int) {
    
    countDownTimer = object : CountDownTimer(3000 * <number of words>, 1000) { // starts at 3 seconds
    
        override fun onTick(secondsUntilDone: Long) {
            if (secondsUntilDone > 9000) {
                Log.i("We're done!", "No more countdown")
                changingWord.text = titleShift[0]
                println(titleShift[0])
            } else if (secondsUntilDone > 6000) {
                Log.i("We're done!", "No more countdown")
                changingWord.text = titleShift[1]
                println(titleShift[1])
            }
            .
            .
            .
            etc
        }
    
        override fun onFinish() {
        }
    }.start()}
    
  2. 如果你仍然坚持使用上述方法,那么你所需要做的就是提供时间作为输入。 所以你的代码看起来像这样

    fun WordChanger(num: Int, time: Long) {
    
    val countDownTimer = object : CountDownTimer(time, 1000) { // starts at 3 seconds
    
        override fun onTick(secondsUntilDone: Long) {
    
        }
    
        override fun onFinish() {
            Log.i("We're done!", "No more countdown")
            changingWord.text = titleShift[num]
            println(titleShift[num])
        }
    }.start()}
    
     WordChanger(0, 3000) 
     WordChanger(1, 6000) 
     WordChanger(2, 9000) 
     WordChanger(3, 12000) 
     WordChanger(4, 15000)
    

让我知道你是否需要任何解释


This is because you are starting all the timers at once and not one by one like you want to. There are a few ways that you can do this

  1. Just use one single CountDownTimer and update the data inside onTick method based on how much time has elapsed

    fun WordChanger(num: Int) {
    
    countDownTimer = object : CountDownTimer(3000 * <number of words>, 1000) { // starts at 3 seconds
    
        override fun onTick(secondsUntilDone: Long) {
            if (secondsUntilDone > 9000) {
                Log.i("We're done!", "No more countdown")
                changingWord.text = titleShift[0]
                println(titleShift[0])
            } else if (secondsUntilDone > 6000) {
                Log.i("We're done!", "No more countdown")
                changingWord.text = titleShift[1]
                println(titleShift[1])
            }
            .
            .
            .
            etc
        }
    
        override fun onFinish() {
        }
    }.start()}
    
  2. If you still insist on using the above approach than what you need to do is provide the time as an input as well. So your code would look like this

    fun WordChanger(num: Int, time: Long) {
    
    val countDownTimer = object : CountDownTimer(time, 1000) { // starts at 3 seconds
    
        override fun onTick(secondsUntilDone: Long) {
    
        }
    
        override fun onFinish() {
            Log.i("We're done!", "No more countdown")
            changingWord.text = titleShift[num]
            println(titleShift[num])
        }
    }.start()}
    
     WordChanger(0, 3000) 
     WordChanger(1, 6000) 
     WordChanger(2, 9000) 
     WordChanger(3, 12000) 
     WordChanger(4, 15000)
    

Let me know if you need any explanation

相关问答

更多
  • Kotlin的合成性质不是魔术,而且工作方式非常简单。 当您访问btn_K ,它调用getView().findViewById(R.id.btn_K) 。 问题是你正在访问它太早了。 getView()在onCreateView返回null 。 尝试使用onViewCreated方法: override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { btn_K.setOnClickListener { Log.d(TAG ...
  • 你可以通过调用TextView的构造函数,如下所示: var textview = TextView(this) // "this" being the Activity 请参阅官方文档中的创建实例 。 You can, by calling the constructor of TextView, like so: var textview = TextView(this) // "this" being the Activity See creating instances in the offic ...
  • 使用android提供的Timer ,并从头开始教程,看看这个 。 Use the Timer which android provides and for a from the scratch tutorial, check out this.
  • 您不会更改适配器内容 - 您只需设置新变量tempArray值。 tempArray = taiwan电话适配器后,仍然保持相当于options变量的数据。 编辑 对不起,第一个代码示例 - 我不知道ArrayAdapter不支持内容更改。 我从来没有为自己编辑它。 :)我经常使用自定义适配器 - 它也可能是您的解决方案。 使用MutableList类型更好地制作tempArray变量。 然后改变它的内容。 tempArray.clear() tempArray.addAll(taiwan) 此代码更改适 ...
  • 这是因为你正在开始所有的计时器,而不是像你想的那样一个接一个。 有几种方法可以做到这一点 只需使用一个CountDownTimer并根据经过多少时间更新onTick方法中的数据 fun WordChanger(num: Int) { countDownTimer = object : CountDownTimer(3000 * , 1000) { // starts at 3 seconds override fun onTick(secondsUntilDon ...
  • 我同意W /从Dimitar的其他答案,你可能不想用线性布局来做这件事。 但是,如果你必须,你是否在添加新视图之后在LinearLayout上调用invalidate()? I agree w/ the other answer from Dimitar that you probably don't want to do this with a linear layout. However if you must, are you calling invalidate() on the LinearLay ...
  • 取得了预期的效果。 主要活动: override fun onResume(){ super.onResume() val bundle : Bundle? = intent.extras if (bundle != null){ transitionToNotificationOpen ...
  • 数据绑定库的当前版本使用kotlin。 我相信您看到的消息是因为该库使用的是kotlin版本0.12.613。 在reddit上对此进行了一些讨论。 您可以尝试更新到最新版本的数据绑定库1.0-rc4 ,看看它们是否已更新到M14。 The current version of the databinding library is using kotlin. I believe the message you are seeing is because the library is using kotlin ...
  • 您正在使用segue在VC1和VC2之间进行转换。 当您从VC2返回时,您正在创建一个全新的VC1,这就是您没有看到标签更新的原因。 您应该使用展开segue从VC2返回VC1。 请参阅此处了解如何设置和使用展开segue。 由于您使用滑动手势在视图之间进行切换,因此您需要以编程方式调用unwind segue 。 请参阅本答案的后半部分,了解如何设置展开segue并为其指定一个标识符,以便您可以从滑动处理程序函数中使用performSegue(withIdentifier:sender:)调用它。 You ...
  • android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 这就是问题 您必须将更新ui的后台任务部分移动到主线程上,或者在UI线程中创建mHandler; 更新: 从计时器更新UI: http : //android-developers.blogspot.com/2007/11/stitch-in ...

相关文章

更多

最新问答

更多
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • 电脑高中毕业学习去哪里培训
  • 电脑系统专业就业状况如何啊?
  • IEnumerable linq表达式(IEnumerable linq expressions)
  • 如何在Spring测试中连接依赖关系(How to wire dependencies in Spring tests)
  • Solr可以在没有Lucene的情况下运行吗?(Can Solr run without Lucene?)
  • 如何保证Task在当前线程上同步运行?(How to guarantee that a Task runs synchronously on the current thread?)
  • 在保持每列的类的同时向数据框添加行(Adding row to data frame while maintaining the class of each column)
  • 的?(The ? marks in emacs/haskell and ghc mode)
  • 一个线程可以调用SuspendThread传递自己的线程ID吗?(Can a thread call SuspendThread passing its own thread ID?)
  • 延迟socket.io响应,并“警告 - websocket连接无效”(Delayed socket.io response, and “warn - websocket connection invalid”)
  • 悬停时的图像转换(Image transition on hover)
  • IIS 7.5仅显示homecontroller(IIS 7.5 only shows homecontroller)
  • 没有JavaScript的复选框“关闭”值(Checkbox 'off' value without JavaScript)
  • java分布式框架有哪些
  • Python:填写表单并点击按钮确认[关闭](Python: fill out a form and confirm with a button click [closed])
  • PHP将文件链接到根文件目录(PHP Linking Files to Root File Directory)
  • 我如何删除ListView中的项目?(How I can remove a item in my ListView?)
  • 您是否必须为TFS(云)中的每个BUG创建一个TASK以跟踪时间?(Do you have to create a TASK for every BUG in TFS (Cloud) to track time?)
  • typoscript TMENU ATagParams小写(typoscript TMENU ATagParams lowercase)
  • 武陟会计培训类的学校哪个好点?
  • 从链接中删除文本修饰(Remove text decoration from links)