今天遇到个需求,可能有同时两个方法写入同一个excel。
- 怎么能让一个方法同时被调用,创建线程就行了
- 为什么用匿名内部类的形式创建thread及两种实现多线程的基本方式
-
static不能向上抛出异常了 - 即使不是static,实现Runnable接口不能抛异常只能捕获异常
- main里不能访问实例方法,只能静态方法
- java中方法必须写在类体里
- 为什么要向上转型而不是直接声明子类引用(Dog dog=new Dog())?
怎么能让一个方法同时被调用,创建线程就行了
首先是一个方法被同时调用,开始我还不会怎么能让一个方法被同时执行。后来搜到创建线程就行了。
需要同时执行的方法像下面createExcelFile()这样
1 | public synchronized static void createExcelFile(String excelPath) throws IOException { |
new Thread长这样
1 | Thread threadOne = new Thread(new Runnable() { |
为什么用匿名内部类的形式创建thread及两种实现多线程的基本方式
本来向main里抛出异常,main直接调用createExcelFile()没啥事但是,这么创建thread就报错了,加了@SneakyThrows就行了。为什么呢?大概是因为thread是以内部类形式创建的。(那我现在去看下内部类https://www.cnblogs.com/dolphin0520/p/3811445.html )发现有成员内部类 局部内部类 匿名内部类。这个属于匿名内部类。不对啊 虽然下面这种形式也是可以的,但是还是要加@SneakyThrow,为什么呢?
1 | static class Runnable1 implements Runnable{ |
这种写法虽然能达到一样的效果,但是既冗长又难以维护。
那么问题来了,使用匿名内部类创建线程的好处是什么?但是,如果一个只使用一次,那么将其编写为独立的一个类岂不是很麻烦?这个时候就应该想到匿名内部类了,匿名内部类就此诞生了!
不得不说匿名方法最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口。
首先,多线程的实现方式两种:一种是继承Thread类,另一种是实现Runnable接口。
Thread类是Runnable接口的一个实现类
看两种实现多线程的基本方式(不实用匿名内部类)
继承Thread:
1 | class MyThread extends Thread{ |
实现Runnable:
1 | class MyThread implements Runnable{ |
可知最后:无论哪种方法都需要实现run()方法,run方法是线程的运行主体。并且,线程的运行都是调用Thread的start()方法。
那么代理模式中Thread类就充当了代理类,它在线程运行主体运行前作了一些操作然后才运行线程的run()。总之,Thread提供了很多有关线程运行前、后的操作,然后通过它的start()方法让JVM自动调用目标的run()方法。
static不能向上抛出异常了
之前的问题为什么不能向上抛出呢?跟匿名内部类没有一点关系是因为静态代码块中的异常原则上必须处理,不应该也不能再往上抛原因:在类加载器,加载该类时,首先执行的就是static{}块中的代码,如果static{}块中的异常没有处理,异常就会导致该类加载失败,也就是说“该类夭折,不存在”,显然与其相关的操作肯定就不能执行当然了,如果你“不得不”向外抛可以这样写:(用InputStream举例,可根据你自己的代码修改一下)https://bbs.csdn.net/topics/310071083
1 | static { |
即使不是static,实现Runnable接口不能抛异常只能捕获异常
我去掉static发现还是不能抛,为什么?
因为run()方法是Runnable接口里面的方法,而Runnable接口在定义run()方法的时候没有抛出任何异常,所以子类在重写run()方法的时候要小于或等于父类(Runnable)的run()方法的异常,所以父类没有抛出异常,子类不能抛出异常
那我上面说的static不能抛到底是不是对的啊?好像完全没有问题啊。static方法完全可以抛出异常啊。那上一段我就划掉了。
main里不能访问实例方法,只能静态方法
顺便插一嘴因为main是static,所以不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。
java中方法必须写在类体里
再顺便插一嘴,java中方法必须写在类体里。我他妈居然才知道。
为什么要向上转型而不是直接声明子类引用(Dog dog=new Dog())?
比如设计一个父类 FileRead 用来读取文件,ExcelRead 类和 WordRead 类继承 FileRead 类。在使用程序的时候,往往事先不知道我们要读入的是 Excel 还是 Word。所以我们向上转型用父类去接收,然后在父类中实现自动绑定,这样无论你传进来的是 Excel 还是 Word 就都能够完成文件读取。
下面两篇关于为什么不要声明子类引用讲得挺好的 内容差不多 忘了多看看。
https://blog.csdn.net/TNTZS666/article/details/80273986
http://c.biancheng.net/view/6521.html
可是我试了试上面说的,发现纯属放屁。
1 |
|