线程通信/String相关
线程通信
wait() : 一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
notify() : 一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
notifyAll() : 一旦执行此方法,就会唤醒所有被wait的线程
说明:
wait()、notify()、notifyAll()三个方法必须使用在同步代码块或同步方法中。
三个方法的调用者中必须是同步代码块或同步方法的同步监视器
否则,会出现IllegalMonitorStatteException 异常
面试题:
sleep() 和 wait() 的异同?
相同点:一旦执行方法,都可以使得当前线程进入阻塞状态。
不同点:1.两个方法声明的位置不同:Thread类中声明sleep(),Object类中声明wait()
2.调用的要求不同:sleep()可以在任何需要的场景下调用。wait()必须使用在同步代码块中。
3.关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不释放同步监视器。
方式三:实现Callable接口
与实现Runnable相比:
相比run() 方法,可以有返回值
方法可以抛出异常
支持泛型的返回值
需要借助Future Task 类,比如获取返回结果
方式四:使用线程池
提供指定线程数量的线程池
执行指定的线程的操作,需要提供实现Runnable 接口或Callable接口实现类的对象
关闭连接池
好处:1.提高响应速度(减少了创建新线程的时间)
2.降低资源消耗:重复利用线程池中线程,不需要每次都创建
3.便于线程管理
corePoolSzie() : 核心池的大小
maximunPoolSize:最大线程数
keepAliveTime:线程没有创建任何时最多保持多长时间后会终止
常用类
String
声明为final的,不可被继承
String 实现了Serializable接口 : 表示字符串是支持序列化的
实现了Comparable接口:
内部定义了 final char[] value 用于存储字符串数据,代表不可变的字符序列:不可变性;
通过字面量的方式给一个字符串赋值,此时的字符串值声明在字符串常量池中,字符串常量池不会储存相同内容的字符串。
通过自变量的方式进行赋值,存储的是相同的地址。不管是字面量赋值的,还是new赋值的,其最终指向的都是方法区中的字符串常量池,但new的方式,其对象存的是堆空间中的地址,字面量的方式,直接指向了字符串常量池
面试题:String s = new String("abc"); 方式创建对象,创建了几个对象?
两个,堆空间一个,方法区一个。
常量与常量的拼接结果是在常量池的。且常量池中不会存在相同内容的常量。
只有其中有一个是变量,结果就在堆中(相当于new了对象)。
如果拼接的结果调用了inturn()方法,返回值就在常量池中。
常用方法
compareTo(); //先的减后的 负数:当前对象小
contains() ; // 包含子串
StringBuffer 和 StringBuilder
三者的异同:
String:不可变的字符序列,底层使用char[];
StringBuffer:可变的字符序列; 线程安全的,效率低。底层使用char[];
StringBuilder:可变的字符序列;线程不安全,效率高;底层使用char[];
append() ; 有返回值。可链式调用