zoukankan      html  css  js  c++  java
  • Java线程入门(Thread)

           线程概念:现代操作系统在运行一个程序时,会为其创建一个进程。例如,启动一个Java程序,操作系统就会创建一个Java进程。现代操作系统调度的最小单元是线程,也叫轻量级进程(LightWeight Process),在一个进程里可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。处理器在这些线程上高速切换,让使用者感觉到这些线程在同时执行。

       一.线程状态

    1. NEW : 没有start的线程
    2. RUNNING :可运行线程,可能正在执行,也可能正在等待操作系统中的其他资源,比如cpu时间片
    3. BlOCKED:受阻塞并且正在等待监视器锁(monitor lock)的线程状态
    4. WAITING :一个正在无限期等待另一个线程执行一个特别的动作的线程处于这一状态
    5. TIMED_WAITING:一个正在限时等待另一个线程执行一个动作的线程处于这一状态
    6. TERMINATED:已经退出的线程

        二.状态分析

    1.  NEW:new Thread()后,没有调用start()方法前
    2.  RUNNING :线程正常运行中,但是也不是 每个时间片段都在执行,cpu分配给当前线程的时间片内执行
    3.  BlOCKED:等待获取监视器锁以期进入同步代码块/方法,如进入synchronized方法,被阻塞
    4.  WAITING:不带超时值的Object.wait方法被调用  ||  不带超时值的Thread.join方法被调用  ||  不带超时值的LockSupport.park方法被调用
    5. TIME_WAITING:Thread.sleep 方法被调用  ||  带有超时值的Object.wait 被调用  || 带有超时值的Thread.join 被调用 ||  LockSupport.parkNanos 被调用 || LockSupport.parkUntil 被调用
    6. TERMINATED:线程结束  

           LockSupport类处于sun包下面,里面的方法都是调用Unsafe类(操作内存空间),一般情况下不会手动调用

            Java线程状态变迁图

         三.常见方法

             join()   很多情况,主线程创建并启动子线程,如果子线程中需要进行大量的耗时计算,主线程往往早于子线程结束。这时,如果主线程想等待子线程执行结束之后再结束,比如子线程处理一个数据,主线程要取得这个数据,就要用join() 方法

             yield()  线程让步。顾名思义,就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉,让自己或者其它的线程运行,注意是让自己或者其他线程运行,并不是单纯的让给其他线程

             interrupt()  标记线程中断      

             1. 线程调用sleep,wait,join等方法,并抛出一个InterruptedException。

             2. 线程处于Running状态,只是线程的interrupt标记被设置为true,线程本身的运行不会受到任何影响

               interrupt()  ,   isInterrupted()  ,  interrupted()   三者的区别

    public class InterruptDemo {
        public static void main(String[] args) {
            Thread.currentThread().interrupt();//中断标识
            System.out.println(Thread.currentThread().isInterrupted());//判断中断标识  返回结果true
            System.out.println(Thread.interrupted());//返回当前中断状态,重置中断标识     返回结果true
            System.out.println(Thread.currentThread().isInterrupted());//判断中断标识  返回结果false
        }
    }

           wait()和notify(),notifyAll()配套使用:   wait()释放锁,等待唤醒    notify() 唤醒一个线程    notifyAll() 唤醒全部线程

          

          使用jps+jstack工具查看线程状态:  jstack + 进程ID

           测试代码

    public class ThreadStatusDemo {
        public static void main(String[] args) {
            Object lock1 = new Object();//lock
            Object lock2 = new Object();//lock
    
            new Thread(() -> {//RUNNABLE 状态
                synchronized (lock1) {
                    while (true) { }
                }
            }, "status-thread-1").start();
    
            new Thread(() -> {//TIME_WAITING 状态
                try {
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "status-thread-2").start();
    
            new Thread(() -> {//BLOCKED 状态
                synchronized (lock1) { }
            }, "status-thread-3").start();
    
            new Thread(() -> {//WAITING 状态
                try {
                    synchronized (lock2) {
                       lock2.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "status-thread-4").start();
    
        }
    }

  • 相关阅读:
    ORACLE的主要进程DBWn,LGWR的工作原理
    ORACLE PGA
    如何精确获取ORACLE的秒?
    Dictionary.TryGetValue 方法 试用记 Mark
    在C#中如何实现Form与Form之间的通信
    在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: 命名管道提供程序, error: 40 无法打开到 SQL Server 的连接)
    在C#程序中实现插件架构
    兄弟,你有弄过TestDriven.NET吗?
    由C#风潮想起的-给初学编程者的忠告
    今天真是不在状态的一天,又是一个书写的错误(本文仅为提醒自己,你可以选择跳过)
  • 原文地址:https://www.cnblogs.com/dyg0826/p/10408102.html
Copyright © 2011-2022 走看看