并发编程---- 线程的优先级,协作,通信

线程的生命周期:

并发编程---- 线程的优先级,协作,通信_第1张图片
yield 方法 :将线程从运行转到可运行状态。

直接调用run方法,相当于 main 线程的调用

调用 start 方法,相当于新建的那个线程调用了 run 方法。

线程的优先级:

线程的优先级为 1-10 ,如果不设置 默认为5 通过setPriority 方法来设置。1为最高优先级。

守护线程

和主线程共死的,主线程退出了 守护线程也会退出。所以守护线程中的finally代码块 不能保证一定执行。

线程间的共享

synchronized 内置锁: 保证只能有一个线程 处于同步块之中

  • 方法上没有 static 关键词 为对象锁 锁的是 new 出来那个对象的实例。不同的对象锁之间 可以并行。
  • 方法上有 static 为类锁 锁的是每个类的 class 对象。类锁与对象锁之间也可以并行。

volatile 关键字,最轻量的同步机制。 只有一个线程写,多个线程读。只能确保可见性。

ThreadLocal 的使用 :

public class UseThreadLocal {

    static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
        @Override
        protected Integer initialValue() {
            return 1;
        }
    };

    /**
     * 运行三个线程
     */
    public void startThreadArray() {
        Thread[] threads = new Thread[3];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new TestThread(i));
        }
        for (Thread thread : threads) {
            thread.start();
        }
    }

    public class TestThread implements Runnable {

        int id;

        public TestThread(int id) {
            this.id = id;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " is start");
            Integer integer = threadLocal.get();  // 获得变量的值
            integer =integer + id;
            threadLocal.set(integer);
            System.out.println(Thread.currentThread().getName() + ": " + threadLocal.get());
        }
    }

    public static void main(String[] args) {
        UseThreadLocal useThreadLocal = new UseThreadLocal();
        useThreadLocal.startThreadArray();
    }

}
线程间协作(通信)

轮询:难以保证及时性,资源开销很大

通知和等待

  • wait() 对象上的方法。
  • notify/notifyall 对象上的方法

等待和通知标准范式:

  • 等待方: 获取对象的锁,.循环里判断对象是否满足,不满足调用wait 方法, 条件满足执行业务逻辑.
  • 通知方: 获取对象的锁; 改变条件;通知所有等待在对象的线程

notify和notifyAll应该用谁?

应该尽量使用notifyAll,使用notify因为有可能发生信号丢失的的情况,因为当有很多个线程都在等待的时候,有可能唤醒的不是想运行的那个线程。

join方法(可以让线程有序的执行)

线程A,执行了线程B的join方法,线程A必须要等待B执行完成了以后,线程A才能继续自己的工作。

package com.jym.thread;

/**
 * @program: jym-concurrent
 * @description:
 * @author: jym
 * @create: 2020/05/20
 */
public class UseJoin {

    public static class JumpQueue implements Runnable {

        private Thread thread;

        public JumpQueue(Thread thread) {
            this.thread = thread;
        }

        @Override
        public void run() {
            try {
                thread.join();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " is over");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread currentThread = Thread.currentThread();
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new JumpQueue(currentThread), String.valueOf(i));
            System.out.println(currentThread.getName() + " jump a queue the thread: " +thread.getName());
            thread.start();
            currentThread = thread;
        }
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName() + " is over");
    }
}
调用yield() 、sleep()、wait()、notify()等方法对锁有何影响?

线程在执行yield()以后,持有的锁是不释放的

sleep()方法被调用以后,持有的锁是不释放的

调动方法之前,必须要持有锁。调用了wait()方法以后,锁就会被释放,当wait方法返回的时候,线程会重新持有锁。

调动方法之前,必须要持有锁,调用notify()方法本身不会释放锁的

你可能感兴趣的:(多线程)