首先了解一下JVM、栈和堆
1栈:JVM中一个线程一个栈内存,栈内存是独立的,栈中储存局部变量,所以局部变量的内存不共享,不会存在线程问题。
2堆:JVM中只有一个堆,堆内存是多线程共享的,堆内存中储存的是对象,java对象内部储存成员变量/实例变量,所以实例变量有可能存在线程问题。
3 JVM中只有一个方法区,发放区存在多线程共享,方法区中储存的静态变量存在线程安全问题。
进程:是指一段正在执行的程序,二线程有时也叫做轻量级进城。
线程:是指程序在执行过程中,能够执行程序代码的一个执行单元。
一个进城可以有多个线程。
同步和异步: 可以通过synchronized来实现同步操作。
线程的生命周期分为五种状态:
1 新建 2 就绪 3 运行 4 死亡 5 阻塞
线程的创建有三种方式,一种是 继承thread类,重写run()方法 另一种是 实现Runnable接口,实现run()方法第三种是实现Callable接口,重写call()方法
Callable比Ruannable的功能强大,主要表现在
1 Callable可以在任务结束是有返回值,ruannable 没有
2 Callable可以抛出异常,ruannable没有
3 运行Callable可以拿到一个Future对象,表示异步计算的结果,提供检查计算的是否完成的方法。
star()方法和run()方法的区别:
start()方法是异步执行的,而run方法是同步执行,只有调用线程类的star()方法才能达到多线程的目的。
多线程同步的实现的方法有哪些?
(1) 通过synchronized关键字 (synchronized方法 还有 synchronized块)
(2) wait() 方法和notify()方法
(3) Lock JDK 5 新增加的特性
sleep() 方法和wait() 方法有什么区别?
sleep()是使线程短暂休息一会的方法而 wait() 是一种使线程暂停执行的方法。
(1)原理不同: sleep()方法是thread类的静态方法 ,是线程用来控制自身流程的,他会暂停一段时间,等时间到了会进入苏醒。
wait() 方法是object类中的方法,用于线程之间的通信,会使拥有该对象锁的进程等待,直到其他线程调用notify() 方法时,才能醒来
(2)对锁的处理机制不用: sleep()方法的主要作用是让线程休息一会等时间到了则自动恢复,不涉及到线程通信问题,所以不会释放锁,当调用wait()
方法后,线程会释放掉他 当前占用的锁,从而使线程所在对象的其他synchronized数据可以被别的线程使用。
(3) 使用区域不同: 由于wait()方法的特殊意义,因此它必须放在同步控制方法或者 同步语句块中 使用,而sleep则可以在任意地方
使用
引申 : sleep () 和yield() 方法有什么区别?
(1) sleep() 方法给其他线程运行机会时不考虑线程的优先级,会给低优先级的线程运行机会,而yield()方法只会给相同优先级或更高优先级线程以运行的机会。
(2) 线程执行sleep()方法时会转入阻塞状态,所以在指定的时间内肯定不能被执行,而yield() 方法只是使当前线程重新回到课执行的状态,所以执行yield()方法的线程有可能在进入到可执行状态中又被执行到。
(3) sleep() 方法声明抛出一个InterruptedException,而yield() 方法没有。
(4) sleep() 方法比yield() 有更好的 移植性(与操作系统有关)
终止线程的方式有哪些?
3中方式
1 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
2 thread.stop() 这种相当于直接拔掉电源
2 thread.interrupt() 来终止线程,这个会抛出一个异常,通过捕获异常信息而跳出run()达到终止线程的方式
什么是守护线程?
守护线程是程序在 运行时,在后台提供的一种通用服务的线程,典型例子就是垃圾回收器
守护线程和用户线程几乎一样,只不过如果所有的用户线程都退出了运行,只剩下守护线程,那么JVM就会停止,守护线程也就退出了
。守护线程无非就是在用户线程启动前调用对象的setDaemon(true)的方法
join方法的作用:
让调用该方法的线程在执行完run()方法后,在执行run()方法后面的代码