java线程整理

java线程整理,第1张

java线程整理

线程笔记
  • 1、线程的状态:
  • 2、BLOCKED 和 WAITING 的区别
  • 3、线程优先级
  • 4、线程的常用方法
    • 1、wait()
    • 2、join()
    • 3、yield()
    • 4、sleep()

线程(Thread)是并发编程的基础,也是程序执行的最小单元。

一个进程中可以包含多个线程;
多个线程可以共享一块内存空间和一组系统资源。

线程之间奇幻更加轻量化和节省资源

1、线程的状态
  • NEW:新建状态,线程被创建出来,但尚未启动时的线程状态
  • RUNNABLE:就绪状态,表示可以运行的线程状态,它可能正在运行,或者是在排队等待 *** 作系统给它分配 CPU 资源;
  • BLOCKED:阻塞等待锁的线程状态,表示处于阻塞状态的线程正在等待监视器锁,比如等待执行 synchronized 代码块或者使用 synchronized 标记的方法;
  • WAITING:等待状态,一个处于等待状态的线程正在等待另一个线程执行某个特定的动作,比如,一个线程调用了 Object.wait() 方法,那它就在等待另一个线程调用 Object.notify() 或 Object.notifyAll() 方法;
  • TIMED_WAITING:计时等待状态,和等待状态(WAITING)类似,它只是多了超时时间,比如调用了有超时时间设置的方法 Object.wait(long timeout) 和 Thread.join(long timeout) 等这些方法时,它才会进入此状态;
  • TERMINATED,计时等待状态,和等待状态(WAITING)类似,它只是多了超时时间,比如调用了有超时时间设置的方法 Object.wait(long timeout) 和 Thread.join(long timeout) 等这些方法时,它才会进入此状态;终止状态,表示线程已经执行完成。
2、BLOCKED 和 WAITING 的区别
	虽然 BLOCKED 和 WAITING 都有等待的意思,但二者有着本质的区别,首

先它们状态形成的调用方法不同,其次 BLOCKED 可以理解为当前线程还处于活跃状态,只是在阻塞等待其他线程使用完某个锁资源;而 WAITING 则是因为自身调用了 Object.wait() 或着是 Thread.join() 又或者是 LockSupport.park() 而进入等待状态,只能等待其他线程执行某个特定的动作才能被继续唤醒,比如当线程因为调用了 Object.wait() 而进入 WAITING 状态之后,则需要等待另一个线程执行 Object.notify() 或 Object.notifyAll() 才能被唤醒。

3、线程优先级
//在 Thread 源码中和线程优先级相关的属性有 3 个:
// 线程可以拥有的最小优先级
public final static int MIN_PRIORITY = 1;

// 线程默认优先级
public final static int NORM_PRIORITY = 5;

// 线程可以拥有的最大优先级
public final static int MAX_PRIORITY = 10

线程的优先级可以理解为线程抢占 CPU 的概率,优先级越高的线程优先执行的概率就越大,但并不能保证优先级高的线程一定先执行。

在程序中我们可以通过 Thread.setPriority() 来设置优先级,setPriority() 源码如下:

public final void setPriority(int newPriority) {

    ThreadGroup g;

    checkAccess();

    // 先验证优先级的合理性

    if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {

        throw new IllegalArgumentException();

    }

    if((g = getThreadGroup()) != null) {

        // 优先级如果超过线程组的最高优先级,则把优先级设置为线程组的最高优先级

        if (newPriority > g.getMaxPriority()) {

            newPriority = g.getMaxPriority();

        }
        setPriority0(priority = newPriority);
    }
}

4、线程的常用方法 1、wait()
wait方法是Object对象的方法

wait方法会将当前线程放入wait set,等待被唤醒,并放弃lock对象上的所有同步声明,当前线程会因为线程调度的原因处于休眠状态而不可用。只有通过以下四个方法可以主动唤醒:

  1. notify

  2. notifyAll

  3. Thread.interrupt()

  4. 等待时间过完。

2、join()

在一个线程中调用 other.join() ,这时候当前线程会让出执行权给 other 线程,直到 other 线程执行完或者过了超时时间之后再继续执行当前线程,join() 源码如下:

public final synchronized void join(long millis)

throws InterruptedException {

    long base = System.currentTimeMillis();

    long now = 0;

    // 超时时间不能小于 0

    if (millis < 0) {

        throw new IllegalArgumentException("timeout value is negative");

    }

    // 等于 0 表示无限等待,直到线程执行完为之

    if (millis == 0) {

        // 判断子线程 (其他线程) 为活跃线程,则一直等待

        while (isAlive()) {

            wait(0);

        }

    } else {

        // 循环判断

        while (isAlive()) {

            long delay = millis - now;

            if (delay <= 0) {

                break;

            }

            wait(delay);

            now = System.currentTimeMillis() - base;

        }

    }

}

从源码中可以看出 join() 方法底层还是通过 wait() 方法来实现的。

3、yield()

yield会释放CPU资源,它会使调用线程放弃CPU使用权,加入到同等优先级队列的末尾,让优先级更高(至少是相同)的线程获得执行机会;
如果调用线程是优先级最高的唯一线程,yield方法返回后,调用线程会继续运行;

4、sleep()

sleep当传入参数为0时,和yield相同;当传入参数大于0时,也是释放CPU资源,当可以让其它任何优先级的线程获得执行机会;

假设当前进程只有main线程,当调用yield之后,main线程会继续运行,因为没有比它优先级更高的线程;而调用sleep之后,mian线程会进入TIMED_WAITING状态,不会继续运行;

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5482246.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存