线程简介

Posted yanghe123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程简介相关的知识,希望对你有一定的参考价值。

线程简介
线程的存在就是充分使用CPU资源。
线程的五种状态
新建、就绪、运行、阻塞、死亡
 
新建
当程序通过new关键字创建一个线程之后,该线程就处于新建状态
线程的创建方式有三种:
  • 继承Thread类创建线程类,重写run方法。
  • 实现Runnable接口
  • 实现Callable接口 该方式有返回值

 

就绪
当线程对象调用start() 方法,该线程就进入就绪状态。该状态线程并没有开始运行,只是表示该程序可以运行了。
 
注意事项:
调用start()启动线程而不是run。
如果直接调用run()系统会把run当成普通方法去执行,系统把线程让程一个普通对象,无法并发执行。
 
运行
当线程得到CPU资源就进入运行状态。
 
阻塞
线程进入阻塞状态的情况:
  • 线程调用sleep()方法主动放弃所占用的处理器资源
  • 线程调用了一个阻塞IO方法,在该方法返回之前,该线程被阻塞 如:读操作
  • 线程试图获得一个同步监视器,但监视器正在被其他线程对象所持有。 如:同步代码块
  • 线程等待某个通知(notify) 线程调用wait方法,线程进入挂起状态。
  • 程序调用suspend()方法线程将被挂起。但这个方法容易导致死锁。
线程解除阻塞状态【重新进入就绪状态】:
  • sleep()方法过了指定时间,睡眠时间结束
  • 阻塞IO方法已经返回
  • 该线程成功获得监视器资源
  • 线程等待通知时,接收到一个通知 。 notify/notifyAll
  • 线程调用resume恢复方法
 
死亡
线程死亡后,调用start()方法无法重新启动,死亡就是死亡
线程死亡的三种方式:
  • 线程执行结束
  • 线程抛出一个未捕获的异常
  • 调用stop() 结束线程,但是容易导致死锁
 
 
线程实现方式一:继承Thread类
技术图片
/**
 * @Author YangHe
 * @Date 2020/4/7 11:52
 */
public class ThreadTest extends Thread {
    private int j;
    public ThreadTest(String name){
            super(name);
    }
    public ThreadTest(ThreadGroup threadGroup,String name){
        super(threadGroup,name);
    }
    @Override
    public void run() {

            for(;j<100;j++){
                System.out.println(getName()+"       "+j +" "+getThreadGroup().activeCount()); //显示该线程组活跃的线程数
                if(j==50){
                    Thread.yield();       //当变量值为50 放弃当前资源  进入就绪状态
                  /*  try {
                        Thread.sleep(1000); //当变量值为50 睡眠一秒 进入阻塞状态
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }*/
                }
            }
    }

    public static void main(String[] args) {
        ThreadTest t=new ThreadTest("6666666666");
        t.setDaemon(true);//该线程设置为后台线程,所有线程结束该线程结束
        t.start();
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"  "+i);
            if(i==20){
                ThreadGroup threadGroup=new ThreadGroup("测试");//新建线程组 ,设置线程组名称
                ThreadTest t1=new ThreadTest(threadGroup,"杨贺");
                ThreadTest t2=new ThreadTest("李小艺");
                t1.start();
                t2.start();
            }
        }
    }
}
View Code
线程实现方式二:实现Runnable接口
技术图片
/**
 * @Author YangHe
 * @Date 2020/4/7 11:52
 */
public class RunnableTest implements Runnable{
    private int j;
    @Override
    public void run() {
        for(;j<100;j++){
            System.out.println(Thread.currentThread().getName()+"       "+j);
        }
    }
    public static void main(String[] args) {
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"  "+i);
            if(i==20){
                RunnableTest r=new RunnableTest();
                new Thread(r,"杨贺").start();
                new Thread(r,"李小艺").start();
            }
        }
    }
}
View Code
线程实现方式三:实现Callable接口
技术图片
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * @Author YangHe
 * @Date 2020/4/7 15:47
 */
public class CallableTest implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int i=0;
        for(;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"  "+i);
        }
        return i;
    }

    public static void main(String[] args) throws InterruptedException {
        CallableTest callableTest=new CallableTest();
        FutureTask<Integer> task=new FutureTask<Integer>(callableTest);
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"循环变量的值为 "+i);
            if(i==20){
                Thread t1=new Thread(task,"李小艺");
                t1.start();
                t1.join(); //等待该线程执行完成,主线程再执行
            }
        }
        try{
            System.out.println("子线程的返回值为 "+task.get());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
View Code


以上是关于线程简介的主要内容,如果未能解决你的问题,请参考以下文章

goroutine简介

Android 逆向类加载器 ClassLoader ( 类加载器源码简介 | BaseDexClassLoader | DexClassLoader | PathClassLoader )(代码片段

Android 逆向Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )(代码片段

多线程 Thread 线程同步 synchronized

活动到片段方法调用带有进度条的线程

多个用户访问同一段代码