线程的等待与唤醒
线程的join
需要在几个线程执行完毕之后再执行,例如加载资源等,join方法可以让线程顺序执行
例如
public class Example_1 {
public static void main(String[] args) throws InterruptedException {
Thread threadOne = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("线程1启动");
},"thread-1");
Thread threadTwo = new Thread(() -> System.out.println("线程2启动"),"thread -2 ");
threadOne.start();
threadTwo.start();
threadOne.join();
threadTwo.join();
System.out.println("所有子线程执行完毕");
}
}
join是thread类自带的方法,后续更好的CountDownLatch来使用
yeild方法
yeild方法是线程让出当前cpu的执行权,当前线程会由执行状态转换为就绪状态,cpu会从就绪的线程中选择一个线程继续执行,代码示例:
public class YieldTest implements Runnable{
public YieldTest() {
Thread thread = new Thread(this);
thread.start();
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
if (i % 5 == 0) {
System.out.println(Thread.currentThread() + " yield cup");
}
Thread.yield();
}
System.out.println(Thread.currentThread() + " is over");
}
}
线程的中断
线程死锁
产生的原因
如何破坏死锁
守护线程和用户线程
java中的线程主要分为守护线程和用户线程,当启动一个main函数之后就启动了一个用户线程,JVM内部也存在很多守护线程,例如GC回收线程,他们的区别就是当最后一个非守护线程退出之后,JVM会正常退出,不管守护线程是否退出
创建守护线程
public class DaemonThread {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
for (;;) {
}
});
//设置该线程为守护线程
thread.setDaemon(true);
thread.start();
}
}
ThreadLocal
ThreadLocal主要作用是创建线程本地变量,是变量在每个线程本地的一个副本
public class ThreadLocalTest {
private static ThreadLocal<String> localVariable = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(() -> {
localVariable.set("thread one local variable ");
print("threadOne");
System.out.println("threadOne remove after" + ":" + localVariable.get());
}).start();
new Thread(() -> {
localVariable.set("thread two local variable");
print("threadTwo");
System.out.println("threadTwo remove after" + ":" + localVariable.get());
}).start();
}
private static void print(String str) {
System.out.println(str + ":"+ localVariable.get());
//清除当前线程的本地内存中的值
localVariable.remove();
}
}