java学习笔记20-java高级

多线程的启动调用start方法,而不是run方法,都调用run方法的话会顺序执行 调用start方法首先会判断线程是否已经启动,已启动就会抛出 一个非法的线程状态异常(这是一个运行时期异常),如果没有启动会调用一个start0()方法来调用操作系统资源.
.java文件被编译成.class文件后,依靠JVM可以执行,但JVM也是调用操作系统执行,操作系统需要调用它的资源(CPU,内存,IO等),不同OS调用资源有它自己的算法,当然每个算法都会有它的对外的本地函数.Thread.start()方法调用后,线程未启动的话会调用start0()方法,这个方法就是操作系统的本地函数
JNI是指java本地接口(Java Native Interface)

Thread类也实现了Runnable接口 target类也需实现Runnable接口 多线程使用了代理设计模式 虽然最后执行的不是run方法,但是执行start方法后,内部还是让Runnable的实现类执行了run方法,仍是典型的代理模式

多线程开发的本质实质上就是多个线程之间可以进行同一资源的抢占 Runnable重点描述的是资源(同一资源),Thread描述的是线程(多个线程对象,多个用户)

一般的开发多线程就用Runnable接口,但它有一个缺点,那就是执行完毕后没有返回值. java.util.concurrent.Callable接口有返回值

Callable接口中只有一个call方法,如何使它和Thread类产生关系呢,需要借助FutureTask的构造方法传入一个Callable的实现类,而FutureTask类实现了RunnableFuture接口,该接口又继承了Runnable接口和Future接口(该接口可获得返回值),所以可以将FutureTask类传入Thread类作为Target,这样就实现了一个有返回值的线程任务方法

既然主方法是main线程,每个线程也都有自己的名字,那么进程是谁呢?每当使用java命令执行程序的时候,就表示启动了一个JVM进程,可以启动多个JVM进程.在任何的开发之中,主线程可以创建若干个子线程,主线程负责整体流程,子线程负责耗时操作

Thread类中提供了线程中断的方法和判断的方法 public void interrupt() public boolean isInterrupt()
所有正在执行的线程都是可以被中断的,中断线程必须进行异常的处理

所谓线程强制执行指的是当满足某些条件后,某一线程将一直独占资源,直到该线程的任务执行完毕 public final void join() 强制执行
线程礼让,指的是当前执行的线程,让出资源,让别的线程去执行 public static void yield() 线程礼让只会让出当次的资源
从理论上讲,线程的优先级越高,越有可能先执行(先抢占到资源),有两个方法设置优先级和获取优先级 public final setPriority(int newPriority) public int getPriority()
定义了3个数字常量来代表优先级 public static final int MAX_PRIORITY =10/NORM_PRIORITY=5/MIN_PRIORITY=1 主线程的优先级是中等,一般的线程也是中等

同步来解决线程安全问题,同步会导致性能下降 若干个线程访问同一资源的时候要进行同步,但同步过多的话会造成死锁

syncronized可以保持数据的一致,但是不能避免数据的重复 notify()唤醒第一个等待的线程

线程强制停止的方法都过时了,因为它们可能造成线程的死锁 优雅的停止线程,是定义一个while(flag)循环,flag定义在类成员中默认是TRUE,主线程 Thread.sleep(XXXX) flag=false. 这样来停止

设置为守护线程 public final setDaemon(Boolean on) 判断是不是pubic final boolean isDaemon() 守护线程是围绕在用户线程的周围,如果程序执行完毕那么守护线程也就终止了(即使有任务也不执行了)
GC是java中最大的守护线程,如果程序执行完毕那么GC也将消失

volatile关键字用于属性定义,表示此属性为直接数据操作,而不进行副本的拷贝处理 普通的变量处理都是副本拷贝进行运算然后替换原内存空间数据 使用volatile关键字仍需使用syncronized关键字实现同步

字符串常量池分为静态常量池和运行时常量池 字符串的匿名对象就是在静态常量池中
StringBuffer是线程安全的 有String类没有的insert功能
insert(int index,String s) 在指定索引插入指定字符串 delete(index index) 删除从索引x到索引x的数据 reverse()实现字符串反转 StringBuilder 和StringBuffer是基本一样的,但StringBuffer的方法都是加syncronized修饰的是线程安全的 StringBuffer是jdk1.0提供的 StringBuilder是JDK1.5之后提供的

String StringBuilder StringBuffer 都实现了CharSequence接口 都是它的子类,字符串类的charAt length 等方法都是覆写的此接口的方法

AutoCloseable接口,实现此接口并结合异常处理可实现资源的自动关闭,jdk1.7以后出现的

RunTime是一个描述系统资源信息的类 JVM要执行程序都需要借助操作系统的资源(内存\CPU\io等),通过操作系统提供的本地函数,获取系统资源信息,创建Runtime类的实例(构造方法私有,单例的)
finalize()使终结 此方法在jdk1.9时过时,建议实现AutoCloseable接口 新一代的做法都是开启一个线程单独处理,结合了自动关闭资源及异常处置的使用

Object类中一个clone方法可以实现对象的复制 但是类必须实现了cloneable接口才可以被克隆,此接口没有任何方法,只代表一种能力 clone()方法是被protect修饰的 不能直接调用需要覆写父类方法调用父类方法

为了处理double无法装下的大数字,所以新设置了两个大数字操作类 BigInteger和BigDecimal 这两个类是Number类的子类 开发中能不要就别用,因为性能很差

Date类其实就是long的一个包装类,内部提供了long和日期的转换方式 Date date=new Date(long xxx) long xx=date.getTime()

java.text包中提供了simpleDataFormart类 java.util.regex正则开发包

使用正则最大的特点在于方便进行验证处理,以及方便进行复杂字符串的修改处理 Pattern模式 Matcher匹配

常用正则表达式:
1.数量单个: 字符匹配 任意单个字符表示 任意单个字符 , \表示\ \t表示制表符 \n表示换行符
2.数量单个:字符集匹配(可以从中任选一个) [abc] 表示可能是a,b,c中的任意一个 [^abc]表示不是a,b,c中的任意一个 [a-zA-Z]表示由任意一个字母组成,不区分大小写 [0-9]表示由一位数字组成
3.数量单个:简化字符集匹配 .表示任意一个字符 \d表示任意一个数字 \D表示任意一个不是数字的字符 \s匹配任意一位空格(空格,制表符.换行符) \S匹配任意一位不是空格的字符 \w表示字母数字下划线中任意一位 \W表示非字母数字下划线中的任意一位
4.边界匹配 ^匹配边界开始 $匹配边界结束
5.数量表达 表达式? 表示该正则可以出现0次或一次 表达式* 表示该正则可以出现0次1次或多次 表达式+ 该正则可以出现一次或多次
表达式{n} 表示该表达式可以出现n次 表达式{n,} 表示该表达式可以出现n次或n次以上 表达式{n,m} 表示该表达式可以出现n次到m次
6.逻辑表达式 XY 表示一个正则后紧跟着另一个正则 X|Y 表示匹配正则X或者Y (X)表示括号内为一个整体的正则表达式

正则不能进行含义的判断,只能判断格式 String类的正则功能是正则最基本的,而更加复杂的正则功能则需要java.util.regex 包下的Pattern Matcher来实现

国际化就是利用区域编码加载文字显示信息 java.util包中有一个专门用于描述区域和语言的类Locale 中文的代码时 zh_CN 美国英语的代码时 en_US Locale.getDefault()获取默认的区域和语言
在Locale类中主要的国家(语言)都设置成了常量直接调用即可

baseName描述的是资源名称,但是没有后缀 ResourceBundle 资源包,包含特定于语言环境的对象 资源文件中的{0} {1}都是占位符,有这些的都需要利用MessageFormat类进行格式化

java.lang.ThreadLocal该类提供了线程局部变量,相当于操作同一资源时把一个抽屉变成了多个抽屉每个线程有自己独立的抽屉,否则多线程会出现数据不一致的情况. 该类用来存放数据,为每个线程提供了标记,每个线程只能操作自己的数据

TimerTask是一个抽象类.它实现了Runnable接口,因为每一个定时任务都是一个独立的线程在控制 它的实现类中需覆写run方法,这是任务主题 Timer类的对象负责执行任务 以及间隔执行 timer.schedule() timer.scheduleFixedRate()

Base64是一种加密算法 jdk1.8提供了此类 Base64.getEncoder().encode()编码 Base64.getDecoder.decode()解码

自定义的一个类是无法使用系统提供的数组或集合排序操作的,因为排序的原理是因为实现了Comparable接口 所以要进行比较的话需实现此接口 当然也可以实现Compartor接口进行自定义比较
Compartor属于一种挽救型的比较器,针对前期设计未实现Comparable接口现在又不能改变源代码的情况,实现精确排序

java.lang.Compareable是定义类的时候实现的一个父接口,主要用于按照自然顺序排序,只有一个compare to 方法 java.util.Compartor是作为一个挽救的比较器,需要设置单独的比较器规则类实现排序.里面有compare方法,可作为某些方法的参数进行传递

文件输出的时候,父目录必须存在 Writer有一个append方法可以追加输出 Writer使用到了缓冲区,如果没有关闭流的话是不会输出结果的 字符流肯定有一个缓冲区,来处理接收到二进制数据转换为字符

ByteArrayInPutStream ByteArrayOutPutStream CharArrayWriter CharArrayReader 内存操作流 也是子类 左右特色的方法就是OutPutStream toByteArray()可以获取流中数据的字节数组 可以存数据

PipeInPutStream PipeOutPutStream 管道流可以实现线程之间的通信 主要方法是 pipeOutPut.connect(pipeInPutSream) 进行管道的连接

字符流与字节流的本质区别是字符流又多了一个将字节转换为字符的缓冲区(磁盘到内存->CPU都是二进制的数据,能读出字符是因为加了一个缓冲区) Reader的子类是InPutStreamReader,孙类是FileReader
Writer的子类是OutPutStreamWriter,孙类是FileWriter

打印流的继承关系 OutPutStream子类是FilterOutPutStream孙类是PrintStream 构造方法中只能传递OutPutStream writer子类直接是PrintWriter,构造方法不仅能传递Writer还能传递OutputStream

System类中三个常量 public static final PrintStream out(标准输出/显示器输出) public static final Printstream err(错误输出) public static final InPutSream in(标准输入/键盘输入)

实际开发中所有的内容输入都是字符串类型的,方便进行正则处理及转换 java.util.scanner 使用Scanner输入数据的一个最大的特点是可以利用正则验证数据 Scanner取代了BufferReader来接收输入数据

在以后的开发过程中程序的输出一定使用输出流,文件输入使用Scanner 或BufferReader,首选Scanner scanner.useDelimiter(String str) 设置读取分割符

对象序列化,对象正常情况下是存在于堆内存中,如果想要将对象数据保存到硬盘或发送到其他服务器,保存到数据库,就需要将对象进行二进制转换

序列化和反序列化需要用到两个流,ObjectInPutStream 和ObjectOutPutStream

猜你喜欢

转载自blog.csdn.net/wwzzh1989/article/details/89209188
今日推荐