java线程基础

github: https://github.com/ValjeanShaw
blog: https://valjeanshaw.github.io/
优快云: https://blog.youkuaiyun.com/im_xiao

创建java线程的两种方式和启动

  1. 继承Thread类

    继承Thread类,然后重写run()方法,通过线程的start()开启线程

    public class RunByThread extends Thread{
    
        @Override
        public void run(){
            while(true){
                try{
                    Thread.sleep(5000);
                    System.out.println("running by thread......");
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
    
  2. 实现Runnable接口

    与Thread类似,实现Runnable接口,重写其中的run()方法,通过线程的start()开启线程。

    public class RunByRunnable implements Runnable {
    
        public void run() {
            while(true){
                try{
                    Thread.sleep(1000);
                    System.out.println("running by runnable......");
                }catch (InterruptedException e){
                    System.out.println("interrupted...");
                    e.printStackTrace();
                }catch (Exception e){
                    e.printStackTrace();
                }
    
            }
        }
    }
    

    3.启动线程

    ​ 继承Thread类的子类,可通过[1.创建新对象]或者[2.创建对象放入Thread类]来创建线程

    ​ 实现Runnable接口的方法,通过新建对象,放入Thread类中来创建线程。因为Runnable接口只有run()方法。

    ​ 使用Thread提供的start()方法启动线程

    public class StartThead {
        public static void main(String[] args) {
    		//继承Thread类的方法,可以通过以下两种方法开启线程
            //1.  创建实例
            RunByThread runByThread = new RunByThread();
            runByThread.start();
            //2.  创建对象,放入Thread中
            Thread threadRun = new Thread(new RunByThread());
            threadRun.start();
            threadRun.isInterrupted();
    
    		//实现Runnable接口的方法,通过以下一种方法开启线程。
            //创建对象,放入Thread中
            Thread thread = new Thread(new RunByRunnable(),"runByThread");
            thread.start();
        }
    }
    

线程的优先级别

现代操作系统基本采⽤时分的形式调度运⾏的线程,操作系统
会分出⼀个个时间⽚,线程会分配到若⼲时间⽚,当线程的时间⽚
⽤完了就会发⽣线程调度,并等待着下次分配。

设置线程的优先级,目的是按照线程优先级给线程分配时间片的多少,优先级越高,时间片越多。

  • 优先级范围: 1-10
  • 方法 setPriority(int)

代码实例:

public class RunByRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }


    public static void main(String[] args) {
        RunByRunnable runByRunnable = new RunByRunnable();
        Thread thread1 = new Thread(runByRunnable,"run1");
        Thread thread2 = new Thread(runByRunnable,"run2");
        Thread thread3 = new Thread(runByRunnable,"run3");
        Thread thread4 = new Thread(runByRunnable,"run4");
        thread1.setPriority(5);
        thread2.setPriority(3);
        thread3.setPriority(8);
        thread4.setPriority(1);


        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }

}

(敲黑板!!)在不同的JVM以及操作系统上,线程规划会存在差异,有些操作系统甚⾄会忽略对线程优先级的设定。so: 线程优先级不能作为程序正确性的依赖

线程的状态

java线程中一共有6种状态:

  1. new 新创建状态,还未调用start()方法
  2. runnable 运行状态,java中,将就绪和运行统称“运行中”
  3. blocked 阻塞状态,线程阻塞于锁
  4. waiting 等待状态,一直等待通知或中断
  5. time_waiting 超时等待,等待通知或中断,超时后自动返回
  6. terminated 当前线程已经执行完毕

Daemon线程

​ Daemon线程即为守护线程,是一种支持性线程,主要用于程序后台中支持性工作。例如垃圾回收。当一个Java虚拟机不存在非Daemon的时候,Java虚拟机会自动退出,不论Daemon是否执行完毕,是什么状态。

​ 方法: thread.setDaemon(true);

以下代码,可测试Daemon的运行是否会被强制杀掉

public class DaemonThread extends Thread {
    @Override
    public void run() {
        try {
            System.out.println("DaemonThread running start");
            TimeUnit.SECONDS.sleep(1);
            System.out.println("DaemonThread running end");
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("DaemonThread  InterruptedException");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("DaemonThread  exception");
        } finally {
            System.out.println("DaemonThread finally");
        }
    }

    public static void main(String[] args) {
        DaemonThread daemonThread = new DaemonThread();
        daemonThread.setDaemon(true);
        daemonThread.start();
    }
}

执行结果:


DaemonThread running start


该程序有两个线程,一个主线程,一个被设置为Daemon的线程。守护线程开始执行后,进入睡眠状态。然后主线程执行完毕,这时JVM发现没有了非守护线程,于是直接退出了。Daemon线程中未执行完的代码,也不会再执行。

线程中断的概念和使用

​ 中断可以理解为线程的一个标识位状态。它表示一个运行中的线程是否被其它线程进行了中断操作。

​ 使用:

A线程对B线程要进行中断: 在A中调用,B.interrupt();

B线程对A线程进行响应:通过调用方法 isInterrupted()方法判断是否被打断,true为中断过,false为未中断过。

标识位复位:Thread.interrupted

​ 当线程为终结状态,即使线程被中断过,标志位也为false
当抛出InterruptedException异常时,jvm会先将中断标志位清除,所以isInterrupted() 为false。

实例代码

public class ThreadInterrupt {
    public static void main(String[] args) {
        //sleepThread不停的尝试睡眠
        Thread sleepThread = new Thread(new SleepRunner(), "sleepThread");
        sleepThread.setDaemon(true);
		//budyThread线程一直在执行
        Thread busyThread = new Thread(new BusyRunner(), "busyThread");
        busyThread.setDaemon(true);

        sleepThread.start();
        busyThread.start();

        //休眠几秒钟,让两个线程充分运行
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        sleepThread.interrupt();
        busyThread.interrupt();

        System.out.println("sleepThread interrupted is " + sleepThread.isInterrupted());
        System.out.println("busyThread interrupted is " + busyThread.isInterrupted());

        //防止两个线程提前退出
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

class SleepRunner implements Runnable {

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class BusyRunner implements Runnable {

    @Override
    public void run() {
        while (true) {
			//xxx 爱执行什么执行什么吧
        }
    }
}

执行结果


sleepThread interrupted is false
busyThread interrupted is true
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at ThreadPackage.SleepRunner.run(ThreadInterrupt.java:57)
at java.lang.Thread.run(Thread.java:748)


抛出InterruptedException的线程,中断位被清除了,另外一个线程,就没有被清除

总结

本篇文章主要讲解Java线程的基础,使用。重点在于Java线程的创建和开启。

全部代码见:

​ https://github.com/ValjeanShaw/MyConcurrent/tree/develop/src/main/java/ThreadPackage

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值