面向对象的编程-Application 27

Previously on OOP:

How to read a file line by line, split the line into several fields, and fill them to Java Generics was the topic discussed in the last article.

在本文中,我们会进入Tread章节的学习。Thread的程序并不在本课程的考试范围内,所以各位宝宝们不用纠结于这一章的代码,把重点放在理论部分的理解上。

现在有一个非常简单的需求:

这个需求可以用线程来实现。

既然选用线程来实现,那么我们首先要创建一个线程。Thread类的constructor需要的参数是一个Runnable Interface的子类的实例。虽然这个分析过程已经出现过了很多次,但是本黄鸭还是要再重申一遍。一个Interface的实例是不能直接创建的。想要实例的话,只能先创建一个该Interface的子类,可以用普通的类,也可以用inner classes,最后再创建子类的实例。以上整个过程还可以用一个Lambda expression来代替。

本段代码就采用了Lambda expression来创建Runnable Interface的子类的实例。里面的abstract function被改写为while循环体,功能是不停地打印“Duck”字符串。

“不停地打印”和我们的所需要的“每隔一秒钟打印一次”是不同的。要解决这个问题,请看下面的一种方案。

本段代码相比上一段增加了try-catch block,还有sleep()函数。

本黄鸭决定先分析一下try-catch block。这是一种Exception handler的写法,目的是为了handle Thread.sleep()调用时可能出现的Exception。如果对于Thread.sleep()函数有信心(事实上确实不会出太大的问题),那么不写这里的try-catch block也是可以的。在catch block中,有两种写法:

(1)ignore the problem,什么也不做,就当无事发生,继续执行循环体。

(2)打印一点别的字符串,以说明这里曾经出过Exception,再返回到main函数。

再看一下sleep()函数。这个函数能不能实现我们的需求呢?答案是否定的。因为在过完sleep()函数规定的时间之后,线程会进入Runnable state,即排队等待Java virtual machine的scheduler分配CPU时间,直到被scheduler选中,才能回到Running state,开始打印字符串“Duck”。所以从用户的角度上来看,实际sleep的时间一般都要比给定的长。

虽然使用sleep()函数不是一个最佳方案,但是不管怎么说,我们的线程已经创建好了。使用线程的object reference调用start()函数,就能让这个线程在程序运行的时候开始执行。

接下来,让我们了解一下multi-tasking。当线程在打印“Duck”的时候,打开一个输入对话框,线程还能继续执行吗?

如何创建一个输入对话框的是Graphic User Interface章节的内容,会在后面的文章中重点讲解。JOptionPane类可以提供四种弹出对话框,分别是:

(1)showConfirmDialog:有三个按钮yes, not,andcancel

(2)showInputDialog

(3)showMessageDialog:目的在于inform the user that something happened。

(4)showOptionDialog

最后,Thread的执行可以被打断,只要用刚才创建的Thread的object reference来调用interrupt()函数即可。

调用这个函数时,不管线程处于什么样的状态,都会立即被打断,并且收到一个Exception。所以,线程的代码中最好包含一个Exceptionhandler,以备interrupt()触发Exception的剧情。

欢迎使用本黄鸭编写的小程序~

微信公众号二维码:

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181101G1D3VP00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券