ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【Java并发专题之二】Java线程基础

2019-12-16 12:01:16  阅读:213  来源: 互联网

标签:状态 Java Thread thread t1 waiting 线程 之二


使用线程更好的提高资源利用率,但也会带来上下文切换的消耗,频繁的内核态和用户态的切换消耗,如果代码设计不好,可能弊大于利。

一、线程
  进程是分配资源的最小单位,线程是程序执行的最小单位;线程是依附于进程的,一个进程可以生成多个线程,这些线程拥有共享的进程资源;

二、线程生命周期(相关API)
1、5个阶段6种状态
  5个阶段:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)。
  6种状态:

public enum State   
{  
       /** 
        * Thread state for a thread which has not yet started. 
        */  
       NEW,  
         
       /** 
        * Thread state for a runnable thread.  A thread in the runnable 
        * state is executing in the Java virtual machine but it may 
        * be waiting for other resources from the operating system 
        * such as processor. 
        */  
       RUNNABLE,  
         
       /** 
        * Thread state for a thread blocked waiting for a monitor lock. 
        * A thread in the blocked state is waiting for a monitor lock 
        * to enter a synchronized block/method or  
        * reenter a synchronized block/method after calling 
        * {@link Object#wait() Object.wait}. 
        */  
       BLOCKED,  
     
       /** 
        * Thread state for a waiting thread. 
        * A thread is in the waiting state due to calling one of the  
        * following methods: 
        * <ul> 
        *   <li>{@link Object#wait() Object.wait} with no timeout</li> 
        *   <li>{@link #join() Thread.join} with no timeout</li> 
        *   <li>{@link LockSupport#park() LockSupport.park}</li> 
        * </ul> 
        *  
        * <p>A thread in the waiting state is waiting for another thread to 
        * perform a particular action.   
        * 
        * For example, a thread that has called <tt>Object.wait()</tt> 
        * on an object is waiting for another thread to call  
        * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on  
        * that object. A thread that has called <tt>Thread.join()</tt>  
        * is waiting for a specified thread to terminate. 
        */  
       WAITING,  
         
       /** 
        * Thread state for a waiting thread with a specified waiting time. 
        * A thread is in the timed waiting state due to calling one of  
        * the following methods with a specified positive waiting time: 
        * <ul> 
        *   <li>{@link #sleep Thread.sleep}</li> 
        *   <li>{@link Object#wait(long) Object.wait} with timeout</li> 
        *   <li>{@link #join(long) Thread.join} with timeout</li> 
        *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>  
        *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li> 
        * </ul> 
        */  
       TIMED_WAITING,  
  
       /** 
        * Thread state for a terminated thread. 
        * The thread has completed execution. 
        */  
       TERMINATED;  
}

1.1、新建--NEW
New并初始化。
四种方式:
(1)继承Thread类

package test;

public class MyThread extends Thread{

    @Override
    public void run() {
        System.out.println("MyThread is running...");
    }
}

package test;

public class Main {
    public static void main(String[] args){
        new MyThread().start();//创建并启动线程 MyThread is running...
    }
}

(2)实现Runnable接口

package test;

public class MyThread implements Runnable{

    @Override
    public void run() {
        System.out.println("MyThread is running...");
    }
}

package test;

public class Main {
    public static void main(String[] args){
        Thread thread=new Thread(new MyThread());
        thread.start();//MyThread is running...
        //或者new Thread(new MyThread()).start();
    }
}

(3)实现Callable接口


(4)使用线程池

 

1.2 就绪--Runnable
当线程对象调用了start()方法之后,该线程处于就绪状态,JVM会为其创建方法调用栈和程序计数器,等待系统为其分配CPU时间片。

调用start()方法与run()方法,对比如下:
(1)调用start()方法来启动线程,系统会把该run()方法当成线程执行体来处理。但如果直接调用线程对象的run()方法,则run()方法立即就会被执行,而且在run()方法返回之前其他线程无法并发执行。也就是说,系统把线程对象当成一个普通对象,而run()方法也是一个普通方法,而不是线程执行体;
(2)调用了线程的run()方法之后,该线程已经不再处于新建状态,不要再次调用线程对象的start()方法。只能对处于新建状态的线程调用start()方法,否则将引发IllegaIThreadStateExccption异常;

1.3 运行--Running
线程获得了CPU时间片才得以真正开始执行run()方法的线程执行体

1.4 阻塞--Blocked
处于运行状态的线程在某些情况下,让出CPU并暂时停止自己的运行,进入阻塞状态。

阻塞状态分类:
等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程占用),它会进入到同步阻塞状态;
其他阻塞:通过调用线程的sleep()或join()或发出I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕 时,线程重新转入就绪状态;

(1)WAITING:等待状态
线程处于 无限制等待状态,等待一个特殊的事件来重新唤醒,如:

通过wait()方法进行等待的线程等待一个notify()或者notifyAll()方法;
通过join()方法进行等待的线程等待目标线程运行结束而唤醒;

(2)TIMED_WAITING:时限等待状态
线程进入了一个 时限等待状态,如:sleep(3000),等待3秒后线程重新进行 就绪(RUNNABLE)状态 继续运行。

1.5 死亡--Dead
线程会以如下3种方式结束,结束后就处于死亡状态:
(1)run()或call()方法执行完成,线程正常结束;
(2)线程抛出一个未捕获的Exception或Error;
(3)直接调用该线程stop()方法来结束该线程—该方法不安全,通常不推荐使用;

终止(TERMINATED)状态,线程执行完毕后,进入终止(TERMINATED)状态。

package test;

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        Runnable interruptTask = new Runnable() {
            int i = 0;
            @Override
            public void run() {
                try {
                    //在正常运行任务时,经常进行本线程的中断标志,如果被设置了终端标志就自行停止线程
                    while (!Thread.currentThread().isInterrupted()){
                        //休眠100ms
                        Thread.sleep(100);
                        i++;
                        System.out.println(Thread.currentThread().getName() + " 状态(" + Thread.currentThread().getState() + ") loop " + i);
                    }
                }catch (InterruptedException e){
                    //在调用阻塞方法时正确处理InterruptedException异常。(例如,catch异常后就结束线程。)
                    System.out.println(Thread.currentThread().getName() + " 状态(" + Thread.currentThread().getState()
                            + ") catch InterruptedException.");
                }
            }
        };
        Thread t1 = new Thread(interruptTask,"t1");
        System.out.println(t1.getName() +" 状态("+t1.getState()+") is new.");

        // 启动“线程t1”
        t1.start();
        System.out.println(t1.getName() +" 状态("+t1.getState()+") is started.");

        // 主线程休眠300ms,然后主线程给t1发“中断”指令。
        Thread.sleep(300);
        t1.interrupt();
        System.out.println(t1.getName() +" 状态("+t1.getState()+") is interrupted.");

        // 主线程休眠300ms,然后查看t1的状态。
        Thread.sleep(300);
        System.out.println(t1.getName() +" 状态("+t1.getState()+") is interrupted now.");
    }
 
}

结果:

t1 状态(NEW) is new.
t1 状态(RUNNABLE) is started.
t1 状态(RUNNABLE) loop 1
t1 状态(RUNNABLE) loop 2
t1 状态(TIMED_WAITING) is interrupted.
t1 状态(RUNNABLE) catch InterruptedException.
t1 状态(TERMINATED) is interrupted now.

 

标签:状态,Java,Thread,thread,t1,waiting,线程,之二
来源: https://www.cnblogs.com/cac2020/p/12048379.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有