1.HashMap和Hashtable的区别?
HashMap和HashTbale都是接口Map的实现类 所以HashMap和Hashtable都实现了map提供的方法。
Hashtable 的键值对 都不允许为空 如果为空会报空指针异常异常 效率低 但是线程安全
HashMap 的键值对 都允许为空 效率高 适合单线程 线程不安全
2.进程和线程的区别
正在进行或者执行的程序
一个程序一旦运行都会在内存中开辟运行空间那么程序就在其运行空间运行 进程指的是程序的运行空间 进程的作用就是给程序开辟运行的空间的。
程序的运行空间开辟出来以后就是执行程序 所谓的执行程序就是从指定的入口按照一定的顺序加载执行程序的代码内容。程序从指定的入口按照一定的顺序加载执行程序的代码内容这称之为程序的执行顺序一个执行的路径就是一个线程。线程的作用就是执行程序。
一个进程可以有多个线程。
3.线程的实现方式
第一种 继承Thread类
- 继承Thread类并重写run方法
- Run()方法中定义的就是线程执行的任务
- 启动线程
不是调用线程的run方法 调用run方法和调用普通方法没有区别。调用start()方法是启动线程,然后jvm会自动的执行线程的run() 即自动的执行线程任务
第二种 实现Runnable接口
实现Runable接口并重写run方法
- 实现Runable接口的实现类并重写run方法定义线程,而Runbale接口的实现类对象就是线程任务类对象---将线程任务也进行了封装
- 调用Thread类参数就是Runable类型的构造器去创建Thread对象即Thread对象就是创建线程Thread(Runable target,String name)
分配新的Thread对象
Thread(String name)
分配新的Thread对象
创建了线程同时给线程指定了任务
3.调用start()方法 启动线程 jvm会自动的执行线程的run方法既线程任务
第三种 实现Callable接口,以及FutureTask类
它与Runnable相比 Callable功能更强大些
相比run() 方法可以有返回值
方法可以抛出异常
支持泛型的返回值
需要借助FutureTask类 获取返回的结果
关于Future接口的说明:
可以对具体的Runnable Callable任务的执行结果进行取消 查询是否完成获取接口
FutureTask是Future接口唯一的实现类
FutureTask同时实现了Runnable Future接口 它既可以作为Runnable被线程执行也可以作为Future得到Callable的返回值
第四种 线程池 spring线程池
4.线程的生命周期
新建:当一个Thread类或者其子类的对象被声明创建时新生的线程对象就处于新建状态
就绪:处于新建状态的线程被start()后 将进入线程队列等待cpu时间片,此时它已具备了运行的条件 只是还没分配到cpu资源
运行:当就绪状态的线程被调度并获得了cpu资源时便进入了运行状态run()方法定义了线程的操作和功能
阻塞:在某种特殊的情况下 被人为的挂起或执行输入输出操作时,让出cpu并临时终止自己的执行进入阻塞状态
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
死亡:线程完成了他的全部工作或被强制性的终止或出现异常导致结束。
5.wait()和sleep()的区别
相同点:
一旦执行方法都可以使当前线程进入阻塞状态
不同点:
- 俩个方法声明的位置不同。Sleep() 是Thead类的方法wait()是object的方法
- 调用要求不同:sleep() 可以在任意需要的场景下调用 wait()必须在同步代码块和同步方法中调用。
- 关于释放同步锁 如果方法都使用在同步代码块或同步方法中 sleep()不会释放锁
Wait()释放锁
6.反射中获得Class类的方法
- 若已知具体的类,通过class属性获取
比如: Class classzz=String.class;
- 已知某个类的实例调用该实例的getClass()方法获得Class实例
比如:Person p=new Pserson() Class classzz=p.getClass()
- 已知一个类的全类名,通过Class类的静态方法forName获取
比如 Class classzz=Class.forName(“java.lang.String”)
- 通过类的加载器来获取(this指当前类)
例如: ClassLoader c1=this.getClass().getClassLoader()
Class classzz = c1.loadClass(“类的全类名”)