首页 > 编程语言 >线程总述(Java版)

线程总述(Java版)

时间:2022-11-27 19:22:39浏览次数:36  
标签:总述 Java thread Thread start 线程 new public

一、线程创建

1、继承Thread类

  首先,自定义线程类继承THread类;其次,重写run方法,编写线程执行体;最后,创建线程对象并调用start()方法启动线程。但值得注意的是,线程并不一定会立刻执行,而是由CPU进行调度执行。继承Thread类实现线程创建的具体代码如下所示:

 

//自定义线程继承Thread类
public class thread_Thread extends Thread {
    //重写run()方法编写线程执行体
    public void run() {
        for (int i = 0; i<3; i++) {
            System.out.println("listening music---" + i);
        }
    }
    //创建线程对象,调用start()方法启动线程
    public static void main(String[] args) {
        thread_Thread thread = new thread_Thread() ;
        thread.start();
        for (int i = 0; i<3; i++) {
            System.out.println("playing game---" + i);
        }
    }
}

 

  上述程序运行结果如下所示:

 

2、实现Runnable接口

  首先,定义一个类实现接口Runnable;其次,实现run()方法并编写线程执行体;最后,创建线程对象并调用start()方法启动线程。其具体代码实现如下所示:

 

public class thread_Runable_1 implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("runnable接口" + i);
        }
    }

    public static void main(String[] args) {
        //创建实现对象
        thread_Runable_1 thread_Runable_1 = new thread_Runable_1();
        //创建代理类对象
        //Thread thread = new Thread(thread_Runable_1);
        //thread.start();
        new Thread(thread_Runable_1).start();
    }
}

class test implements Runnable{
    public void run(){

    }
}

 

  上述程序运行结果如下所示:

 

  实现Runnable接口时具备多线程能力可以有效地避免单线程的局限性,也能够便于一个对象被单个线程使用,其具体实现代码如下所示:

public class thread_Runable_2 implements Runnable{
    //多个线程同时操作一个对象(买火车票)
    private int ticketnum = 10;
    public void run(){
        while (true){
            if (ticketnum <= 0){
                break;
            }
            System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketnum-- + "张票");
        }
    }
    public static void main(String[] args) {
        thread_Runable_2 thread_Runable_2 = new thread_Runable_2();
        new Thread(thread_Runable_2,"老师").start();
        new Thread(thread_Runable_2,"同学").start();
        new Thread(thread_Runable_2,"黄牛").start();
    }
}

  上述程序的执行结果如下图所示:

 

  值得注意的是,多个线程操作同一资源的情况下则容易产生线程的不安全现象,还可能导致数据紊乱。

3、实现Callable接口

  首先,需要创建一个实现Callable的实现类。再实现call()方法,将此线程需要执行的操作声明在call()中;其次,需要创建Callable接口实现类的对象,并将此Callable接口实现类的对象作为传递到FutureTask构造器中,创建FutureTask的对象;最后,将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()方法。其具体实现代码如下所示:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class thread_Callable {
    public static void main(String[] args){
        CallableThread callableThread = new CallableThread();
        FutureTask futureTask = new FutureTask(callableThread);
        Thread t1 = new Thread(futureTask);
        t1.start();
        try {
            //get()方法的返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值
            Object sum = futureTask.get();
            System.out.println(sum);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

class CallableThread implements Callable {
    @Override
    public Object call() throws Exception {
        int sum = 0;
        for (int i = 0; i <= 10; i++) {
            if (i % 2 ==0){
                System.out.println(i);
                sum += i;
            }
        }
        return sum;
    }
}

  代码运行结果如下所示:

  住的注意的是,与使用Runnable相比,Callable功能更强大;相比于run()方法,call()方法则可以获取返回值,除此之外,call()方法可以抛出异常,被外面的操作捕获,获取异常的信息。Callable支持泛型的返回值,但需要借助FutureTask类,比如获取返回结果。

  Future接口可以对具体RunnableCallable任务的执行结果进行取消、查询是否完成、获取结果等操作。另外,FutureTaskFuture接口的唯一实现类。且当FutureTask同时实现了RunnableFuture接口时,它既可以作为Runnable被线程执行,也可以作为Future得到Callable的返回值。

二、线程状态

  线程状态主要划分为创建状态(new)、就绪状态(ready)、阻塞状态(waiting)、运行状态(running)和死亡状态(dead)五种。

  注意事项:

  ①程序运行至“Thread t = new Thread()”时线程对象实现创建后即进入创建状态。

  ②当调用start()方法时线程进入就绪状态且不立刻调度执行。

  ③当调用sleep、wait或同步锁定是,线程进入阻塞状态,直至阻塞时间结束才重新进入就绪状态并等待CPU调度执行。

  ④只有进入运行状态线程才真正开始执行线程体的代码块。

  ⑤线程中断或结束,线程一旦进入死亡状态就无法再次启动。

三、线程方法

  一般情况下,线程存在开始执行、休眠、礼让、更改优先级、插队等方法,其调用的函数情况具体如下所示:

1、停止线程stop()   一般情况下不建议使用JDK所提供的stop()或destroy()方法停止线程,而是选择设置一个标志进行终止变量(flag)确认,“flag = true”时则线程继续运行;当“flag = false”时则停止线程。其具体实现代码如下所示:
public class Thread_stop implements Runnable{
    //设置标志位
    private boolean flag = true;
    public void run(){
        int i = 0;
        while (flag) {
            System.out.println("run……thread" + i++);
        }
    }
    //设置公开方法停止线程,转换标志位
    public void stop(){
        this.flag = false;
    }
    public static void main(String[] args) {
        //调用stop方法切换标志位进而停止线程
        Thread_stop Thread_stop = new Thread_stop();
        new Thread(Thread_stop).start();
        for (int i = 0; i < 4; i++){
            System.out.println("thread……" + i);
            if(i == 3){
                Thread_stop.stop();
                System.out.println("线程停止");
            }
        }
    }
}
  代码运行结果如下所示:

2、进程休眠sleep()

  sleep()可以模仿网络延时、倒计时等。

  每个对象都有一个锁,sleep不会释放锁。

  sleep()存在异常InterruptedException()。

  sleep()时间到达后线程就可以进入就绪状态。

  sleep(时间)指定当前线程阻塞的毫秒数(1000毫秒=1秒)。

  利用进程休眠方法sleep()可以进行模拟时延操作,进而实现模拟抢票。其具体实现代码如下所示:

public class Thread_sleep_1 implements Runnable{
    //票数
    private int ticketNums = 7;
    @Override
    public void run() {
        while (true) {
            if (ticketNums <= 1){
                break;
            }
            //模拟延时
            try {
                Thread.sleep(100);
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "--->拿到了第" + ticketNums-- + "票");
        }
    }
    public static void main(String[] args) {
        Thread_sleep_1 Thread_sleep_1 = new Thread_sleep_1();
        new Thread(Thread_sleep_1,"老师").start();
        new Thread(Thread_sleep_1,"同学").start();
        new Thread(Thread_sleep_1,"黄牛").start();
    }
}

  上述代码的运行结果如下所示:

  利用进程休眠方法sleep()也可以实现模拟倒计时操作,其具体实现代码如下所示:

public class Thread_sleep_2 {
    public static void main(String[] args) {
        try{
            tendown();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    //模拟倒计时
    public static void tendown() throws InterruptedException {
        int num = 10;
        while (true){
            Thread.sleep(1000);
            System.out.println("倒计时:第" + num-- + "秒");
            if (num <= 0){
                break;
            }
        }
    }
}

  上述代码的运行结果如下所示:

 

 

 3、进程礼让yield()

  线程礼让即暂停当前正在执行中的线程,将线程有运行状态转化成就绪状态而不是进入阻塞状态。线程礼让揖让CPU重新调度线程,但礼让未必能够成功。线程礼让程序具体代码如下所示:

public class Thread_yield {
    public static void main(String[] args) {
        MyYield myYield = new MyYield();
        new Thread(myYield,"A").start();
        new Thread(myYield,"B").start();
    }
}
class MyYield implements Runnable {
    public void run() {
        System.out.println(Thread.currentThread().getName()+"线程开始执行");
        Thread.yield();//礼让
        System.out.println(Thread.currentThread().getName()+"线程停止执行");
    }
}

  上述程序运行结果如下所示:

4、线程合并join()

  join合并线程相当于插队,插队后其他线程进入阻塞状态,待到该线程执行结束后在执行其他线程,其他线程的优先级不变。其具体实现代码如下所示:

public class Thread_join implements Runnable {
    public void run() {
        for (int i = 0; i < 3; i++) {
            System.out.println("我是VIP,我想先执行"+i);
        }
    }
    public static void main(String[] args) throws InterruptedException {
        //启动线程
        Thread_join threadjoin = new Thread_join();
        Thread thread = new Thread(threadjoin);
        thread.start();
        //主线程
        for (int i = 0; i < 7; i++) {
            if (i == 5) {
                thread.join();
            }
            System.out.println("mian" +i );
        }
    }
}

  上述代码的运行结果如下所示:

5、查看线程状态state

  Thread.State线程可处于以下六种状态中的任意一种:

  New:尚未其中的线程所处状态。

  Terminated:一退出线程所处于状态。

  Runnable:在Java虚拟机中执行线程所处状态。

  Blocked:被阻塞而等待监视器锁定的线程所处状态。

  Waiting:正在等待其他线程执行特定功能所处于的状态。

  Timed_waiting:正在等待其他线程执行动作到执行等待时间所处状态。

  线程状态查看的具体代码如下所示:

public class Thread_state {
    public static void main(String[] args) {
        for (int i = 0; i < 1; i++) {
            Thread thread = new Thread(()->{
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
            //开始观察状态
            Thread.State state = thread.getState();
            System.out.println(state); //NEW
            //观察启动后
            thread.start();
            state = thread.getState();
            System.out.println(state);
            while (state != Thread.State.TERMINATED){
                try {
                    Thread.sleep(100);
                    state = thread.getState();
                    System.out.println(state);
                }
                catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            //thread.start();
        }
    }
}

  上述代码运行结果如下所示:

6、线程优先级

  Java中会提供一个线程调度器对程序启动后进入就绪状态的所有线程进行监控,线程调度器会按照优先级来决定线程的调度顺序。此外,线程的优先级用数字表示范围在1到10之间,即:Thread.MIN_PRIORITY=1、 Thread.NORM_PRIORITY=5、Thread.MAX_PRIORITY=10。其具体实现代码如下所示:

public class Thread_priority {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
        MyPriority myPriority = new MyPriority();
        Thread t1 = new Thread(myPriority);
        Thread t2 = new Thread(myPriority);
        Thread t3 = new Thread(myPriority);
        Thread t4 = new Thread(myPriority);
        Thread t5 = new Thread(myPriority);
        Thread t6 = new Thread(myPriority);
        Thread t7 = new Thread(myPriority);
        Thread t8 = new Thread(myPriority);
        //设置线程优先级并启动线程
        t1.start();
        t2.setPriority(1);
        t2.start();
        t3.setPriority(Thread.MIN_PRIORITY);
        System.out.println(t2.getPriority());
        t3.start();
        t4.setPriority(10);
        t4.start();
        t5.setPriority(8);
        t5.start();
        t6.setPriority(Thread.MAX_PRIORITY);
        t6.start();
        t7.setPriority(4);
        t7.start();
        t8.setPriority(6);
        t8.start();
    }
}

class MyPriority implements Runnable{
    public void run() {
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
    }
}

  其中getPriority()可获取线程优先级,setPriority()可设置线程优先级。

  上述代码的运行结果如下所示:

7、守护线程daemon

  线程主要可以划分为用户线程和守护线程两种,虚拟机必须要确保用户线程执行完整却不需要保证守护线程执行完毕,如后台常见的操作日志、监控内存、垃圾回收等。其具体实现代码如下所示:

public class Thread_daemon {
    public static void main(String[] args) {
        God god = new God();
        You you = new You();
        Thread thread = new Thread(god);
        //默认为false,代表为用户线程
        thread.setDaemon(true);
        thread.start();
        new Thread(you).start();
    }
}

class God implements Runnable{
    public void run() {
        while (true){
            System.out.println("上帝守护着你");
        }
    }
}

class You implements Runnable{
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("你每天都过得很开心"+i);
        }
        System.out.println("你没了");
    }
}

  上述代码的运行结果如下所示(仅部分运行结果):

 

标签:总述,Java,thread,Thread,start,线程,new,public
From: https://www.cnblogs.com/Auion-idiot/p/16929631.html

相关文章

  • 21.多线程
    多线程程序同时执行多个任务使用线程可以把占据长时间的程序中的任务放到后台去处理。程序的运行速度可能加快线程实现方法线程是CPU分配资源的基本单位。当一程序......
  • 自用_Minecraft Java Server配置、指令等等提示
    尚未写完gamemode=(模式)//adventure冒险模式、creative创造模式、survival生存模式、spectator旁观者模式。online-mode=//用于验证玩家是否“在线”,也就是是否是正版......
  • 又一巨头从 Java 迁移到 Kotlin,简直很无语。。
    出品|OSC开源社区(ID:oschina2013)Meta发布了一篇博客表示,正在将其Android应用的Java代码迁移到Kotlin,并分享了这一过程中的一些经验。该公司认为,Kotlin是一种流行的......
  • java中时间表达
    初始化Datedate=newDate();输出时间字符串System.out.println(date.toString());字母           描述          ......
  • 学习Java掌握那些知识就入门了
    了解Java的基础Java基本语法、Java平台应用、Java的核心概念:JVM、JDK、JRE以及Java面向对象思想,同时要会学到如何在系统中搭建Java开发环境,以及如何利用第三方工具进行Jav......
  • Java开发学习(四十四)----MyBatisPlus查询语句之查询条件
    1、查询条件前面我们只使用了lt()和gt(),除了这两个方法外,MybatisPlus还封装了很多条件对应的方法。MybatisPlus的查询条件有很多:范围匹配(>、=、between)模糊匹......
  • Java基础_Spring三种构造方法
    第一种构造方法接口:FirstDaopackagecom.leehl.springgitider.dao;publicinterfaceFirstDao{publicvoidsave();}主方法:FirstDaoimplpacka......
  • java——mybatis——Mybatis的CRUD——查询返回行操作
    在第一个xml示例项目的基础上,进行操作: mybatis-config.xml配置文件:<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTDC......
  • java操作hdfs
    1.添加maven依赖,即在pom.xml文件李添加依赖<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://......
  • Failed to start bean 'documentationPluginsBootstrapper'; nested exception is jav
    springboot整合swagger2报错错误如下:Failedtostartbean'documentationPluginsBootstrapper';nestedexceptionisjava.lang.NullPointerException:Cannotinvoke......