Java中的Thread类_java thread-程序员宅基地

技术标签: java  操作系统  

目录

一.什么是Thread类

二.Thread类的基本用法

三.线程的并发执行


一.什么是Thread类

       在java标准库中,提供了一个Thread类,用来表示/操作线程,Thread类可以视为是Java标准库提供的API,Java是支持多线程编程的,在Java中创建好的Thread实例,其实和操作系统中的线程是一一对应的关系,操作系统提供了一组关于线程的API(C语言),Java对于这组API进一步封装之后就变成了Thread类

二.Thread类的基本用法

1.线程创建

①.最简单的创建方式

//最简单的创建线程方式 写一个类继承线程Thread类 再重写run方法
class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("hello thread");
    }

}
public class Demo1 {
    public static void main(String[] args) {
        Thread t = new MyThread();//创建一个线程
        t.start();//表示开启一个线程
    }
}

②.实现runnable接口

//另一种创建线程的方法 实现runnable接口
class MyThread2 implements Runnable{
    @Override
    public void run() {
        System.out.println("hello thread");
    }
}
public class Demo2 {
    public static void main(String[] args) {
        Thread t = new Thread(new MyThread2());//Thread的一种构造方法
        t.start();
    }
}

③.使用匿名内部类

public class Demo3 {
    public static void main(String[] args) {//每一个main都是一个线程  线程是并发执行的
        Thread t = new Thread(){//使用匿名内部类来创建线程实例
            @Override
            public void run() {
                System.out.println("hello thread");
            }
        };
        t.start();
        Thread t2 = new Thread(new Runnable() {//使用匿名内部类来实现runnable接口
            @Override
            public void run() {
                System.out.println("hello thread2");
            }
        });
        t2.start();  
    }
}

④.使用lambda表达式

public class Demo3 {
    public static void main(String[] args) {
        
        //使用lambda表达式来创建线程实例
        Thread t = new Thread(()->{
            System.out.println("hello thread");
        });
        t.start();
    }


}

2.线程休眠

使用sleep()方法


public class Demo4 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while(true){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);//休眠(阻塞状态)1000ms后此线程状态转为就绪状态
                } catch (InterruptedException e) {//常见的线程受查异常 表示线程异常中止
                    e.printStackTrace();
                }
            }
        });
        t.start();//每隔一秒打印一次
       
    }
}

3.线程等待

使用join()方法

public class Demo5 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            for (int i = 0; i < 5; i++) {
               System.out.println("hello thread");
               try {
                   Thread.sleep(1000);
               }catch (InterruptedException e){
                   e.printStackTrace();
               }

           }
        });
        t.start();
        try {
            t.join();//等待 等这个线程完成后才进行其他线程  也可以在括号内加数字表示等待线程结束最多等待多长时间都是ms单位
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hh");
    }
}

4.线程中断

设置标志位

public class Demo6 {
    public static boolean falg = false;
    public static void main(String[] args) {
        Thread t = new Thread(()->{//如何结束一个线程呢 可以设置一个标志位
            while(!falg){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        //只要改变标志位就可以停止
        t.start();
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("结束");
        falg = true;
    }
}

当然Thread类内部包含了一个boolean的变量可以用来作为标记位,标记是否被中断Thread.interrupted()或者Thread.currentThread().isInterrupted()都可以

public class Demo7 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
           while(!Thread.currentThread().isInterrupted()){//Thread内部包含了一个boolean的变量可以用来作为标记位 标记是否被中断 或者使用这个Thread.interrupted()也是可以来标记的,但是前面的更常用,Thread.currentThread().isInterrupted()这个方法是判定Thread的普通成员,每个实例都有自己的标志位
               System.out.println("hello thread");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
                   break;//注意这里的break 没有这个的话进入异常之后还会继续打印的
               }
           }
        });
        t.start();
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.interrupt();//使用thread的对象的interrupt()方法来通知线程结束
    }
}

Thread.interrupted()线程中断会清除标记位,Thread.currentThread().isInterrupted()线程标记位不会被清空

public class Demo8 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.interrupted());
            }
        });
        t.start();
        t.interrupt();//使用者线程中断会清除标记位
        Thread t2 = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().isInterrupted());
            }
        });
        t2.start();
        t2.interrupt();//使用Thread.currentThread().isInterrupted()这个标记位不会被清空
    }
}

5.获得线程实例 

package thread;


public class Demo9 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                //System.out.println(this.getName());//也可以使用this拿到线程实例但是不能在runnable内使用runnable只是一个单纯的任务,没有name属性
                System.out.println(Thread.currentThread().getName() + "存活");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + "死去");//哪个线程调用Thread.currentThread()这个拿到的就是哪个线程的实例
        },"process");

        System.out.println(t.getName() + ":id:" + t.getId());
        System.out.println(t.getName() + ":名称:" + t.getName());
        System.out.println(t.getName() + ":状态:" + t.getState());
        System.out.println(t.getName() + ":优先级:" + t.getPriority());
        System.out.println(t.getName() + ":是不是后台线程:" + t.isDaemon());
        System.out.println(t.getName() + ":是否存活:" + t.isAlive());
        System.out.println(t.getName() + ":是否被中断:" + t.isInterrupted());
        t.start();
        
       while(t.isAlive()){
            System.out.println(Thread.currentThread().getName() + ":状态:" + t.getState());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


    }
}

三.线程的并发执行

线程都是并发执行的

//线程都是并发执行的
public class Demo4 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while(true){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);//休眠1000ms后此线程状态转为就绪状态
                } catch (InterruptedException e) {//常见的线程受查异常 表示线程异常中止
                    e.printStackTrace();
                }
            }
        });
        t.start();//每隔一秒打印一次
        Thread t2 = new Thread(()->{
            while(true){
                System.out.println("hello thread2");
                try {
                    Thread.sleep(1000);//休眠1000ms后此线程状态转为就绪状态
                } catch (InterruptedException e) {//常见的线程受查异常 表示线程异常中止
                    e.printStackTrace();
                }
            }
        });
        t2.start();
        while(true){
            System.out.println("hello main");//main线程
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


    }
}

 但是其结果并不是按什么顺序打印的,这是因为线程虽说是并发执行,但其实这是包含并发+并行的,只要并行的足够快就可以视为并发执行,因此打印出来的并不是按一定顺序的,可以说是无序,随机的,因此我们可以使用等待方法来控制线程执行的顺序,这里主要控制线程结束的先后顺序(调用join后main线程就会进入阻塞状态,等先要执行的线程执行完了之后才会执行main线程,这样就保证了打印的先后顺序,但是这里不会"死等",可以在括号内设置一个时间保证最多等待多长时间)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_58266033/article/details/123638588

智能推荐

光标变成下横线,变回竖线方法_光标怎么变成竖线-程序员宅基地

文章浏览阅读1.1w次,点赞16次,收藏8次。#光标变成下横线,变回竖线方法_光标怎么变成竖线

hadoop2.6.0本地编译,仅作学习记录-程序员宅基地

文章浏览阅读61次。  官网下载hadoop二进制文件,安装部署,可以成功,但是每次运行命令之前均会报错Unable to load native-hadooplibrary for your platformhadoop,经查明为官网提供的是32位,但实际生产环境中一般均需要64位,下面就结合网上资料,整理编译64位hadoop2.6.0 的步骤。  编辑环境为:redhat6.6 +jdk1.7+had..._hadoop2.6.0编译

运行deeplabv3plus-程序员宅基地

文章浏览阅读3k次。1、 参考博客网址:利用deeplab v3+开源代码训练PASCAL VOC 2012数据集https://blog.csdn.net/lfs666666/article/details/83042119论文笔记: DeepLab v3+https://delnasay.github.io/2018/10/14/%E8%AE%BA%E6%96%87%E7%AC%94%E8%AE..._deeplabv3plus

java基础知识-程序员宅基地

文章浏览阅读160次。文章目录基础知识泛型可变参基础知识泛型常用的通配符有T,E,K,V分别表示类型、元素、键、值E 未知的数据类型,在集合中使用T - Type(Java 类) 方法前等等使用可变参* 前提:方法的参数数据类型确定,参数的个数任意* 可变参的语法个数:数据类型…变量名* 可变参数本质上就是一个数组...

[转载]常用CASE工具介绍-程序员宅基地

文章浏览阅读484次。[转载]常用CASE工具介绍 转载自:http://www.cnblogs.com/powerlc/archive/2006/01/12/315959.html ..._case tools都有什么

多线程环境下的单例模式_多线程中使用单例模式-程序员宅基地

文章浏览阅读199次。package com.yunding.concurrent;/** * 多线程环境下的单例模式: doubleChecked + volatile (双重检测 + 避免happenBefore) * * 实例化对象的三个步骤: 1. 开辟空间 2. 初始化对象 3. 把对象的地址赋给引用变量 * * @author beOkWithAnything * */public..._多线程中使用单例模式

随便推点

python PIL.Image使用-程序员宅基地

文章浏览阅读617次。一、 基本概念通道每张图片由一个或多个通道构成RGB图像为例,每张图片由3个通道构成,即R通道,G通道,B通道。对于灰度图像,则只有一个通道。获取图像的通道数量和名称,可以由方法PIL.Image.getbands()获取,此方法返回一个字符串元组,包含每一个通道的名称模式图像的模式定义了图像的类型和像素的位宽。当前支持如下模式:1:1位像素,表示黑和白,但是存储的时候每个像素存储为8..._pil.image 通道

python比较两张图片是否一样_使用PIL(Python成像库)按像素比较两个图像-程序员宅基地

文章浏览阅读293次。I need a function which compares two PIL images of the same size. Let's call them A and B. The result is supposed to be a new image of the same size. If a pixels is the same in both A and B it's suppo..._python diff.convert("rgb")

Android开发点滴 - 实现层级式导航(API 16+)_android studio层级式导航父页面自左至右出现-程序员宅基地

文章浏览阅读439次。在Jelly Bean(API 16)以前,为了实现顶部的导航菜单,程序员们不得不手工写代码,神马在OnCreate啊,神马onOptionsItemSelected啊,但是,现在一切都是浮云了。你需要做的只是在AndroidManifest中增加那么一小句话,指定父Activity就好了。我们来看下代码:...

react打包项目的时候页面空白_react打包为空白 vite.svg为空-程序员宅基地

文章浏览阅读781次。样式图并且控制台报错解决方法和问题原因路径错误,在weback.json里面添加成功图例个人github:https://github.com/webxingkong如有不正确的地方请指教联系修改,后期将不断更新,谢谢你们的支持..._react打包为空白 vite.svg为空

请查收!顶会AAAI 2020录用论文之知识图谱篇_知识图谱论文好发吗-程序员宅基地

文章浏览阅读5.2k次,点赞4次,收藏29次。2020年人工智能顶级会议AAAI录用的知识图谱领域的研究论文已为您准备就绪,请查收!_知识图谱论文好发吗

scapy 内 hexdump 详细使用_scapy hexdump-程序员宅基地

文章浏览阅读2.8k次。起因是之前我在做流量监视器的时候,因为tcp包是分开传输的,所以要想看到一个完整的http请求,需要把包内的内容合并到一起###[ TCP ]### sport = http dport = 2433 seq = 946575688 #这个值就是上一个的seq值加上上一次的传输大小 ack = 3616542016 dataofs ..._scapy hexdump

推荐文章

热门文章

相关标签