多线程第一章

gushilcy / 2024-04-20 / 原文

线程的等待与唤醒

线程的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();
    }
}

第二节

2.1线程的并发与并行