栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java语言基础----常用API03(Thread线程)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java语言基础----常用API03(Thread线程)

线程的第一种创建方式:

继承Thread并重写run方法,在run方法中定义需要并发执行的任务代码。

这种创建线程方式的优点是:结构简单,便于匿名内部类形式创建。
缺点:
1:由于java是单继承的,这导致如果继承了Thread就无法再继承其他类去复用方法,实际开发中会造成很多不便。
2:定义线程时重写了run方法直接将任务定义在了线程中,导致线程与任务存在必然的耦合关系,不利于线程的重用。

public class ThreadDemo1 {
    public static void main(String[] args) {
        Thread t1 = new MyThread1();
        
        t1.start();
    }
}
class MyThread1 extends Thread{
    public void run(){
        for(int i=0;i<1000;i++){
            System.out.println("你是谁啊?");
        }
    }
}
第二种创建线程的方式:

实现Runnable接口单独定义线程任务。

@FunctionalInterface函数式编程

public class ThreadDemo2 {
    public static void main(String[] args) {
        //实例化线程要执行的任务
        Runnable r1 = new MyRunnable1();
        //创建线程来执行对应的任务
        Thread t1 = new Thread(r1);
        t1.start();
    }
}
class MyRunnable1 implements Runnable{
    public void run(){
        for(int i=0;i<1000;i++){
            System.out.println("hello!姐~");
        }
    }
}
Thread常用API

java中所有的代码都是靠线程运行的,main方法也不例外。JVM启动后会创建一个线程来执行,main方法,并且该线程的名字也叫"main",因此我们通常称它为"主线程"。但是它和我们创建的线程并无区别。
static Thread.currentThread()//Thread提供了一个静态方法可以获取运行这个方法的线程

getPriority();//获取线程优先级

线程的优先级:
线程有10个优先级,分别对应整数1-10 其中1为最低优先级,10为最高优先级。5为默认值
,线程start方法调用后便纳入到了线程调度器中统一管理,此时线程只能被动被分配时间片来
并发运行。线程不能主动索取时间片。调度器会尽可能均匀的将时间片分配给每一个线程。
setPriority(1)修改线程的优先级可以增加该线程获取时间片的概率增加。

static  sleep(long ms)//线程静态方法,线程调用sleep后就会进入阻塞状态指定的毫秒。超时后线程会自动回到RUNNABLE状态,再次开始并发运行,线程会释放CPU,阻塞时间到了,线程会重新回到就绪队列

sleep方法要求必须处理中断异常。当一个线程调用sleep方法处于睡眠阻塞的过程中,此时该线程的interrupt()方法被调用时,会立即中断该睡眠阻塞,并抛出中断异常。

public class ThreadInfoDemo {
    public static void main(String[] args) {
        //让主线程执行currentThread以便得到它
        Thread main = Thread.currentThread();//获取到主线程
        dosome();//主线程执行dosome方法

        String name = main.getName();//获取线程的名字
        System.out.println("名字:"+name);

        long id = main.getId();//获取线程的唯一标识
        System.out.println("id:"+id);

        int priority = main.getPriority();//获取线程优先级
        System.out.println("priority:"+priority);

        boolean isAlive = main.isAlive();//线程是否还活着
        boolean isDaemon = main.isDaemon();//线程是否为守护线程
        boolean isInterrupted = main.isInterrupted();//线程是否被中断了
        System.out.println("是否活着:"+isAlive);
        System.out.println("是否为守护线程:"+isDaemon);
        System.out.println("是否被中断:"+isInterrupted);
        Thread.sleep(1000);

    }
    public static void dosome(){
        Thread t = Thread.currentThread();//获取运行dosome方法的线程
        System.out.println("运行dosome方法的线程:"+t);
    }
}

join()可以协调线程的同步运行
多线程是并发运行,本身是一种异步运行的状态。
同步运行:多个线程执行是存在了先后顺序。
异步运行:各自执行各自的

当A线程中调用B.join()后,A线程便进入了阻塞状态。直到B线程执行完毕才会解除A阻塞。
B.join(5000);A线程最多阻塞等待5秒

public class JoinDemo {
    static boolean isFinish = false;//表示图片是否下载完毕

    public static void main(String[] args) {
        Thread download = new Thread(){
            public void run(){
                System.out.println("down:开始下载图片...");
                for(int i=1;i<=100;i++){
                    System.out.println("down:"+i+"%");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("down:图片下载完毕!");
                isFinish = true;
            }
        };

        Thread show = new Thread(){
            public void run(){
                System.out.println("show:开始显示文字");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                }
                System.out.println("show:显示文字完毕!");

                //将show线程阻塞,直到download执行完毕(图片下载完毕)
//                Thread.sleep(?);//无法准确预估download结束时间
                try {
                    
                    download.join();
                } catch (InterruptedException e) {
                }

                System.out.println("show:开始显示图片...");
                if(!isFinish){
                   throw new RuntimeException("图片加载失败!");
                }
                System.out.println("show:图片显示完毕");
            }
        };
        download.start();
        show.start();
    }
}
守护线程

java将线程认为两类:用户线程和守护线程。也称为前台线程和后台线程。
守护线程是通过普通的用户线程通过调用setDaemon(true)设置而转变而来的,必须在该线程调用start()之前设置。
因此创建和使用上与用户线程并无区别。但是主要区别在于:
进程的结束:当一个java进程中所有的用户线程都结束时,进程就会结束,此时会将所有的守护线程全部杀死。​​​​​​​

线程的生命周期

多线程并发安全问题

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1013810.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号