第9章 线程常用操作方法

第9章 线程常用操作方法


本章目标:
  • 了解设置和取得线程名称
  • 了解线程的强制运行
  • 了解线程的休眠
  • 了解线程的礼让
  • 了解线程的中断操作

在多线程中所有的操作方法实际上都是从Thread类开始的,所有的操作基本上都在Thread类之中。
这里写图片描述

一、线程名称


在Thread类之中,可以通过getName()方法取得线程的名称,通过 setName()方法设置线程的名称。

线程的名称一般在启动线程前设置,但也允许为已经运行的线程设置名称。允许两个Thread对象有相同的名字,但为了清晰,应尽量避免这种情况的发生。

另外,如果程序并没有为线程指定名称,则系统会自动地为线程分配一个名称。

package com.java.线程常用操作方法;

public class ThreadNameDemo {
    public static void main(String[] args){
        MyThread mt = new MyThread();    //实例化Runnable子类对象
        new Thread(mt).start();    //系统自动设置线程名称
        new Thread(mt,"线程-A").start();    //手工设置线程名称
        new Thread(mt,"线程-B").start();    //手工设置线程名称
        new Thread(mt).start();    //系统自动设置线程名称
        new Thread(mt).start();    //系统自动设置线程名称
    }
}

/**
 * 实现Runnable接口
 * @author Creator
 *
 */
class MyThread implements Runnable{ 

    /**
     * 覆写run方法
     */
    public void run(){ 
        for(int i = 0; i < 3; i++)
            /*
             * 取得当前线程的名字
             */
            System.out.println(Thread.currentThread().getName()
                    +"运行, i = " + i);
    }
}

程序运行效果:

Thread-0运行, i = 0
Thread-0运行, i = 1
Thread-0运行, i = 2
线程-A运行, i = 0
线程-A运行, i = 1
线程-A运行, i = 2
线程-B运行, i = 0
Thread-1运行, i = 0
Thread-1运行, i = 1
Thread-1运行, i = 2
线程-B运行, i = 1
线程-B运行, i = 2
Thread-2运行, i = 0
Thread-2运行, i = 1
Thread-2运行, i = 2

从执行效果来看,指定的名称会自动出现,如果没有指定会发现线程使用自动编号的方式完成,按照Thread-0,Thread-1….依次编号。实际上在类中存在一个static属性,用于记录编号。

二、取得当前线程


程序可以通过currentThread()方法取得当前正在运行的线程对象。

package com.java.线程常用操作方法;

public class CurrentThreadDemo {
    public static void main(String[] args){
        MyThread02 mt = new MyThread02();    //实例化Runnable子类对象
        new Thread(mt,"线程").start();    //启动线程
        mt.run();      //直接调用run()方法
    }
}

/**
 * 实现Runnable接口
 * @author Creator
 *
 */
class MyThread02 implements Runnable{ 

    /**
     * 覆写run方法
     */
    public void run(){ 
        for(int i = 0; i < 3; i++)
            /*
             * 取得当前线程的名字
             */
            System.out.println(Thread.currentThread().getName()
                    +"运行, i = " + i);
    }
}

运行效果:

main运行, i = 0
main运行, i = 1
main运行, i = 2
线程运行, i = 0
线程运行, i = 1
线程运行, i = 2

此时发现,程序中由主方法直接通过线程对象调用里面的run()方法,所以输出的结果中包含了一个“main”,此线程就是由“mt.run()”产生的。因为调用此语句是由主方法完成的,也就是说实际上主方法本身也是一个线程——主线程。

问题,既然主方法都是以线程的形式出现的,那么JAVA运行时到底启动了多少个线程?

回答:至少启动了2个线程。

  • 从之前学习的知识来看,每当Java程序执行的时候,实际上都会启动一个JVM,每一个JVM实际上就是在操作系统中启动了一个进程。Java中本身具备了垃圾收集机制,所以Java运行时至少启动2个线程:主线程,GC(垃圾回收)。

三、判断线程是否启动


package com.java.线程常用操作方法;

public class ThreadAliveDemo {
    public static void main(String[] args){
        MyThreadAlive mt = new MyThreadAlive();    //实例化Runnable子类对象
        Thread t = new Thread(mt,"线程");    //实例化Thread对象
        System.out.println("线程开始执行之前 --> " + t.isAlive());//判断是否启动
        t.start();  //启动线程
        System.out.println("线程开始执行之后 --> " + t.isAlive());//判断是否启动
        for(int i =0 ; i < 3; i++){
            System.out.println("main运行 --> " + i);
        }
        System.out.println("代码执行之后--> " + t.isAlive());//判断是否启动
    }
}

/**
 * 实现Runnable接口
 * @author Creator
 *
 */
class MyThreadAlive implements Runnable{ 

    /**
     * 覆写run方法
     */
    public void run(){ 
        for(int i = 0; i < 3; i++)
            /*
             * 取得当前线程的名字
             */
            System.out.println(Thread.currentThread().getName()
                    +"运行, i = " + i);
    }
}

运行效果:

线程开始执行之前 --> false
线程开始执行之后 --> true
main运行 --> 0
main运行 --> 1
main运行 --> 2
代码执行之后--> true
线程运行, i = 0
线程运行, i = 1
线程运行, i = 2

四、线程的强制运行


在线程操作中,可以使用join()方法让一个线程强制运行,线程强制运行期间,其他线程无法运行,必须等待此线程完成之后才可以继续运行。

package com.java.线程常用操作方法;

public class ThreadJoinDemo {
    public static void main(String[] args){
        MyThreadJoin mt = new MyThreadJoin();    //实例化Runnable子类对象
        Thread t = new Thread(mt,"线程");    //实例化Thread对象
        t.start();  //启动线程
        for(int i =0 ; i < 50; i++){
            if(i > 10)
                try {
                    t.join();//线程强制运行
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }  
            System.out.println("Main线程运行 --> " + i);
        }
    }
}

/**
 * 实现Runnable接口
 * @author Creator
 *
 */
class MyThreadJoin implements Runnable{ 

    /**
     * 覆写run方法
     */
    public void run(){ 
        for(int i = 0; i < 50; i++)
            /*
             * 取得当前线程的名字
             */
            System.out.println(Thread.currentThread().getName()
                    +"运行, i = " + i);
    }
}

运行效果:

Main线程运行 --> 0
Main线程运行 --> 1
Main线程运行 --> 2
Main线程运行 --> 3
Main线程运行 --> 4
Main线程运行 --> 5
Main线程运行 --> 6
Main线程运行 --> 7
Main线程运行 --> 8
Main线程运行 --> 9
Main线程运行 --> 10
线程运行, i = 0
线程运行, i = 1
线程运行, i = 2
线程运行, i = 3
线程运行, i = 4
线程运行, i = 5
线程运行, i = 6
线程运行, i = 7
线程运行, i = 8
线程运行, i = 9
线程运行, i = 10
线程运行, i = 11
线程运行, i = 12
线程运行, i = 13
线程运行, i = 14
线程运行, i = 15
线程运行, i = 16
线程运行, i = 17
线程运行, i = 18
线程运行, i = 19
线程运行, i = 20
线程运行, i = 21
线程运行, i = 22
线程运行, i = 23
线程运行, i = 24
线程运行, i = 25
线程运行, i = 26
线程运行, i = 27
线程运行, i = 28
线程运行, i = 29
线程运行, i = 30
线程运行, i = 31
线程运行, i = 32
线程运行, i = 33
线程运行, i = 34
线程运行, i = 35
线程运行, i = 36
线程运行, i = 37
线程运行, i = 38
线程运行, i = 39
线程运行, i = 40
线程运行, i = 41
线程运行, i = 42
线程运行, i = 43
线程运行, i = 44
线程运行, i = 45
线程运行, i = 46
线程运行, i = 47
线程运行, i = 48
线程运行, i = 49
Main线程运行 --> 11
Main线程运行 --> 12
Main线程运行 --> 13
Main线程运行 --> 14
Main线程运行 --> 15
Main线程运行 --> 16
Main线程运行 --> 17
Main线程运行 --> 18
Main线程运行 --> 19
Main线程运行 --> 20
Main线程运行 --> 21
Main线程运行 --> 22
Main线程运行 --> 23
Main线程运行 --> 24
Main线程运行 --> 25
Main线程运行 --> 26
Main线程运行 --> 27
Main线程运行 --> 28
Main线程运行 --> 29
Main线程运行 --> 30
Main线程运行 --> 31
Main线程运行 --> 32
Main线程运行 --> 33
Main线程运行 --> 34
Main线程运行 --> 35
Main线程运行 --> 36
Main线程运行 --> 37
Main线程运行 --> 38
Main线程运行 --> 39
Main线程运行 --> 40
Main线程运行 --> 41
Main线程运行 --> 42
Main线程运行 --> 43
Main线程运行 --> 44
Main线程运行 --> 45
Main线程运行 --> 46
Main线程运行 --> 47
Main线程运行 --> 48
Main线程运行 --> 49

五、线程的休眠


使用休眠可以让线程暂停执行。直接使用Thread.sleep()方法。

package com.java.线程常用操作方法;

public class ThreadSleepDemo {
    public static void main(String[] args){
        MyThreadSleep mt = new MyThreadSleep();    //实例化Runnable子类对象
        Thread t = new Thread(mt,"线程");    //实例化Thread对象
        t.start();  //启动线程
    }
}

/**
 * 实现Runnable接口
 * @author Creator
 *
 */
class MyThreadSleep implements Runnable{ 

    /**
     * 覆写run方法
     */
    public void run(){ 
        for(int i = 0; i < 50; i++){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            /*
             * 取得当前线程的名字
             */
            System.out.println(Thread.currentThread().getName()
                    +"运行, i = " + i);
        }
    }
}

运行效果:
这里写图片描述

六、线程的中断


一个线程可以被另外一个线程中断其操作的状态,使用interrupt()方法完成。

package com.java.线程常用操作方法;

public class ThreadInterruptDemo {
    public static void main(String[] args){
        MyThreadSInterrupt mt = new MyThreadSInterrupt();    //实例化Runnable子类对象
        Thread t = new Thread(mt,"线程");    //实例化Thread对象
        t.start();  //启动线程
        try {
            Thread.sleep(2000); //线程休眠2s
        } catch (InterruptedException e) {
        }

        t.interrupt(); //中断线程执行
    }
}

/**
 * 实现Runnable接口
 * @author Creator
 *
 */
class MyThreadSInterrupt implements Runnable{ 

    /**
     * 覆写run方法
     */
    public void run(){ 
        System.out.println("1、进入run()方法");
        try {
            Thread.sleep(10000); //线程休眠10s
            System.out.println("2、已经完成了休眠");
        } catch (InterruptedException e) {
            System.out.println("3、休眠被终止");
            return;  //返回调用处
        }
        System.out.println("4、 run()方法正常结束");
    }
}

运行效果:

1、进入run()方法
3、休眠被终止

七、后台线程


在Java中,只要一个程序没有执行完(一个线程在运行),则整个Java的进程不会消失。所以,此时可以设置一个后台线程,这样即使Java进程结束了,此后台线程依然会继续执行。直接使用setDaemon()方法。

package com.java.线程常用操作方法;

public class ThreadDaemonDemo {
    public static void main(String[] args){
        MyThreadSDaemon mt = new MyThreadSDaemon();    //实例化Runnable子类对象
        Thread t = new Thread(mt,"线程");    //实例化Thread对象
        t.setDaemon(true); //此线程在后台运行
        t.start();  //启动线程
    }
}

/**
 * 实现Runnable接口
 * @author Creator
 *
 */
class MyThreadSDaemon implements Runnable{ 

    /**
     * 覆写run方法
     */
    public void run(){ 
        while(true){
            System.out.println(Thread.currentThread().getName());
        }
    }
}

八、线程的优先级

这里写图片描述

package com.java.线程常用操作方法;

public class ThreadPriorityDemo {
    public static void main(String[] args){
        Thread t1 = new Thread(new MyThreadPriority(),"线程A"); //实例化线程对象
        Thread t2 = new Thread(new MyThreadPriority(),"线程B"); //实例化线程对象
        Thread t3 = new Thread(new MyThreadPriority(),"线程C"); //实例化线程对象
        t1.setPriority(Thread.MIN_PRIORITY);  //优先级最低
        t2.setPriority(Thread.MAX_PRIORITY);  //优先级最高
        t3.setPriority(Thread.NORM_PRIORITY); //普通优先级
        t1.start();  //启动线程
        t2.start();  //启动线程
        t3.start();  //启动线程
    }
}

/**
 * 实现Runnable接口
 * @author Creator
 *
 */
class MyThreadPriority implements Runnable{ 

    /**
     * 覆写run方法
     */
    public void run(){ 
        for(int i = 0; i < 5; i++){
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            /*
             * 取得当前线程的名字
             */
            System.out.println(Thread.currentThread().getName()
                    +"运行, i = " + i);
        }
    }
}

运行效果:

线程B运行, i = 0
线程A运行, i = 0
线程C运行, i = 0
线程B运行, i = 1
线程C运行, i = 1
线程A运行, i = 1
线程B运行, i = 2
线程C运行, i = 2
线程A运行, i = 2
线程B运行, i = 3
线程C运行, i = 3
线程A运行, i = 3
线程B运行, i = 4
线程C运行, i = 4
线程A运行, i = 4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 第1《认识java语言》是介绍Java语言的起源、发展以及特点等基本知识。Java是一种跨平台的高级编程语言,被广泛应用于开发Web和移动应用程序等领域。它具有面向对象、可移植、健壮性好等特点。 第2Java语言基础》是介绍Java语言的基本语法、数据类型、运算符、控制流程等内容。学习这些基础知识对于理解和编写Java程序至关重要。 第3《面向对象程序设计之一》是介绍面向对象编程的原理和基本概念。学习面向对象的思想和方法可以提高程序的可扩展性和重用性。本内容包括类与对象、封装、继承、多态等知识点。 第4《面向对象程序设计之二》是进一步探讨面向对象编程的高级特性。学习抽象类、接口、内部类等内容可以让我们写出更加灵活和健壮的Java程序。 第5Java基础类库》是介绍Java标准库中的常用类和接口。掌握这些类的使用方法可以大大简化程序开发,如字符串处理、集合框架、IO操作等。 第6《图形用户界面程序》是介绍使用Java编写图形用户界面(GUI)程序的方法。学习Swing和JavaFX等技术可以实现丰富、直观的用户界面。 第7《输入输出流》是介绍Java中的输入输出操作。学习文件读写、网络通信等知识可以实现数据的持久化和交互。 第8多线程并发编程》是介绍Java多线程编程的原理和方法。学习多线程操作可以充分利用多核处理器的优势,提高程序的并发性和响应性。 第9《网络编程》是介绍使用Java进行网络通信的方法。学习Socket编程、HTTP协议等内容可以开发出基于网络的应用程序。 第10数据库编程》是介绍使用Java连接和操作数据库的方法。学习JDBC等技术可以实现与数据库的交互,进行数据持久化和查询。 通过学习这些节的内容,可以全面掌握Java语言的基础知识和常用技术,为进一步深入学习和应用Java打下良好的基础。 ### 回答2: 第1:认识Java语言 第1介绍了Java语言的基本概念和特点。Java是一种跨平台的编程语言,被广泛应用于Web开发、移动应用开发等领域。Java具有简单易学的特点,使用了面向对象的编程思想,具有良好的可扩展性和可维护性。 第2Java语言基础 第2主要介绍了Java语言的基本语法和常用的数据类型。包括变量、常量、运算符、流程控制语句等。同时还介绍了Java中的数组、字符串和输入输出等相关知识。 第3:面向对象程序设计之一 第3介绍了面向对象程序设计的基本概念和常用的面向对象的特性。包括类、对象、继承、封装和多态等。同时还介绍了如何定义和使用类,以及如何实现各种面向对象的特性。 第4:面向对象程序设计之二 第4进一步深入介绍了面向对象程序设计的相关知识。包括接口、抽象类、继承和多态的高级应用,以及异常处理和内部类等。这些知识对于构建复杂的面向对象程序非常重要。 第5Java基础类库 第5介绍了Java基础类库中常用的类和方法。包括字符串、日期、时间、集合、文件和输入输出等类库的使用。这些类库为我们提供了丰富的功能,在Java编程中非常实用。 第6:图形用户界面程序 第6介绍了Java图形用户界面编程的相关知识。包括Swing和AWT等GUI库的使用,以及事件处理和布局管理器等。通过学习这些知识,我们可以编写出漂亮、交互性强的图形界面程序。 第7:输入输出流 第7介绍了Java中输入输出流的使用。包括字节流和字符流的概念、File类的使用以及文件读写和网络通信等。这些知识对于实现数据的读写和传输非常重要。 第8多线程并发编程 第8介绍了Java多线程并发编程的相关知识。包括线程线程同步和线程通信的概念,以及锁和条件的使用。同时还介绍了线程池的概念和使用,以及如何处理并发编程中的常见问题。 第9:网络编程 第9介绍了Java网络编程的基本知识。包括Socket编程、TCP和UDP协议,以及HTTP协议的使用。通过学习这些知识,我们可以编写出具有网络功能的Java应用程序。 第10数据库编程 第10介绍了Java数据库编程的相关知识。包括连接数据库、执行SQL语句、事务处理和数据查询等。通过学习这些知识,我们可以使用Java操作各种类型的数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值