1、线程创建的三种方式:
1. 继承Thread类;
2. 实现 runable接口;
3. 实现Callable接口,创建FutureTask对象;
2、线程通知与等待:
(1)wait():在线程调用共享变量的wait()方法,可以使当前线程释放对象锁并让出cpu,通常为避免虚假唤醒,使用如下:
synchronized (obj){
while (条件不满足) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(2)notify()与notifyAll();
3、等待线程执行完毕:join()
4、线程睡眠:sleep(n),让出cpu但不会释放对象锁。
5、让出cpu执行权:yield(),让出cpu执行权,回到就绪状态。
6、线程中断:
interrupt() //中断线程,设置中断标志为true
isInterruped() //获取线程是否被中断
interrupted() //判断线程是否被中断,若中断清除中断标志
7、线程死锁的必要条件:
(1)资源互斥
(2)请求并持有资源
(3)资源不可剥夺
(4)循环等待
8、当所有用户线程执行完毕,无论是否有守护线程在运行,都会退出JVM,只要有一个用户线程未执行完毕,就不会退出JVM。
9、ThreadLocal(线程本地变量):
每个线程都有一个名为threadLocal的成员,类型为HashMap(ThreadLocalMap),其中key
为我们定义的ThreadLocal类型变量的引用,value为我们使用set方法设置的值;每个线程的本
地变量存放在线程自己的threadLocal成员中,如果线程对象不消亡则一直存在,所以需要通过
ThreadLocal对象的remove()方法清除线程的本地变量以防止内存溢出。
10、ThreadLocal不支持继承,即父线程向ThreadLocal变量中设置的值在子线程中不可见;可以使用InheritableThreadLocal代替实现:
public class Test3 {
public static ThreadLocal<String> variable = new ThreadLocal<>();
public static void main(String[] args){
variable.set("main thread");
System.out.println("parentThread:" + variable.get());
Thread thread= new Thread(new Runnable() {
@Override
public void run() {
System.out.println("childThread:" + variable.get());
}
});
thread.start();
}
}
result--------
parentThread:main thread
childThread:null
public class Test3 {
public static InheritableThreadLocal<String> variable = new InheritableThreadLocal<>();
public static void main(String[] args){
variable.set("main thread");
System.out.println("parentThread:" + variable.get());
Thread thread= new Thread(new Runnable() {
@Override
public void run() {
System.out.println("childThread:" + variable.get());
}
});
thread.start();
}
}
result--------------
parentThread:main thread
childThread:main thread