`
HotStrong
  • 浏览: 509581 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Java线程编程基础 第一章

阅读更多

 

 

Java线程编程基础 第一章

 

1、本章任务:建立多线程程序

2、本章知识点:

  •   了解Java线程模型
  •   掌握创建线程的方法
  •   设置线程优先级


3、多线程编程概述

  •   Java提供了对多线程编程的内置支持
  •   多线程程序包括能够并发运行的两个或多个代码段

      单线程、多线程对比示例图:

 

       
    从图中可以看出:
    1.单线程中的3段代码只能在不同的时间点执行,
    2.多线程中的3段代码可以在同一时间点执行

4、进程与线程

  • 进程:一个进程是 一个正在执行的程序 ,目前的操作系统大多都支持同时运行两个或多个程序,称为多任务操作系统
  • 线程:单个程序 可以同时执行 两个或更多的任务 ,每个任务称 一个线程 ,进程包含线程
  • 进程是重量级的任务 ,每个进程都有自己独立的地址空间
  • 线程是轻量级的任务 ,他们共享一个地址空间,共享同一个进程
  • 进程间通信代价昂贵而且受限,线程通信很容易
  • 利用多线程可使你的程序最大限度地利用CPU,因为空闲时间被限制在最小


5、
Thread类和Runnable接口

    Java的多线程系统构建在Thread类 、方法以及Runnable接口 之上。
    可以通过继承Thread类或者实现Runnable接口创建一个新线程
   
    Thread类定义了几个管理线程的方法,常用方法如下:
    方法名            功能
    ====================================
    getName        获取线程名
    getPriority      获得线程的优先级
    isAlive            判定线程是否仍在运行
    join                等待一个线程终止
    run                线程入口方法
    sleep             暂停一个线程一段时间
    start              启动线程

6、程序的主线程


    6.1)主线程描述
    Java程序启动时 (从main方法开始),一个线程 立刻开始运行,这个线程称
    为主线程 ,主线程的重要性体现在如下两个方面:
        1)它是产生其他子线程的线程
        2)一般情况下,必须是最后一个结束 执行的线程,
             因为它要执行各种关闭操作


    主线程不但在程序开始时自动创建,也能通过Thread对象来控制,此时需要
    调用:Thread.currentThread()

    6.2)主线程控制示例代码
   

public static void main(String args[ ]){
        Thread t = Thread.currentThread( ); //获取当前线程(主线程)
        System.out.println("当前线程:" + t); //输出:线程名-优先级-线程组名
        //改变主线程名称
        t.setName("My Thread");         System.out.println("改变之后的名称:" + t);

        //打印数字1 ~ 5,每隔1秒打印1次
        try{
            for(int i = 1; i <= 5; i++){
                System.out.println(i);
                Thread.sleep(1000); //休眠1000毫秒
            }
        }catch(InterruptedException e){
             System.out.println( " 主线程中断! " );
        }
    }

 

7、创建线程

    Java定义了两种 创建线程的方法
    1)可以实现Runnable接口 ,这是创建线程最简单的方法,实现Runnable接口
         只需一个简单的run()方法,其声明如下:
        public void run();
         run()方法是线程的进入点,线程在run方法返回时结束
   
    2)可以继承Thread类 ,重写Thread类的run()方法

8、创建线程
方法1:实现Runnable接口

/**
     * 线程类MyThread,实现Runnable接口
     */
    public class MyThread implements Runnable{ //线程类
        //线程入口点
        public void run(){
            try{
                //打印数字1 ~ 5,每隔500毫秒打印一次
                for(int i = 1; i  <= 5; i++){
                    System.out.println("子线程打印:" + i);
                    Thread.sleep(500); //休眠500毫秒
                }
            }catch(InterruptedException e){
                 System.out.println("子线程中断!");
            }
            System.out.println("子线程执行结束!");
        }
    }
   
    /**
     * 线程类MyThread的测试类
     */
    public class TestMyThread{
        public static void main(String args[ ]){
            //创建线程
            Thread t = new Thread(new MyThread(), "Demo Thread");
            System.out.println("子线程被创建:" + t); //显示线程信息
            t.start(); //启动线程
            //主线程中间隔1秒,打印数字1 ~ 5
            try{
                for(int i = 1; i  <= 5; i++){
                    System.out.println("主线程打印:" + i);
                    Thread.sleep(1000); //休眠1000毫秒
                }
            }catch(InterruptedException e){
                    System.out.println("主线程中断!");
            }
            System.out.println("主线程执行结束!");
        }
    }

 

9、创建线程 方法2:继承Thread类

   

/**
     * 线程类MyThread1,继承Thread类
     */
    public class MyThread1 extends Thread{
        public MyThread1(){
            super("Demo Thread"); //线程命名
        }
        //重写线程入口方法
        public void run(){
            try{
                //打印数字1 ~ 5,每隔500毫秒打印一次
                for(int i = 1; i  <= 5; i++){
                    System.out.println("子线程打印:" + i);
                    Thread.sleep(500); //休眠500毫秒
                }
            }catch(InterruptedException e){
                 System.out.println("子线程中断!");
            }
            System.out.println("子线程执行结束!");
        }
    }
   
    /**
     * 线程类MyThread1的测试类
     */
    public class TestMyThread1{
        public static void main(String args[ ]){
            //创建线程
            Thread t = new MyThread1();
            System.out.println("子线程被创建:" + t); //显示线程信息
            t.start(); //启动线程
            //主线程中间隔1秒,打印数字1 ~ 5
            try{
                for(int i = 1; i  <= 5; i++){
                    System.out.println("主线程打印:" + i);
                    Thread.sleep(1000); //休眠1000毫秒
                }
            }catch(InterruptedException e){
                System.out.println("主线程中断!");
            }
            System.out.println("主线程执行结束!");
        }
    }

 


10、如何选择创建线程的方式

    问: Java有两种创建线程的方式,哪种更好?
   
    1. Thread类定义了多个派生类可以重写的方法,run()方法只是其中之一,
    所以只有在需要增强或者修改Thread类时才应该使用继承Thread类方式
   
    2. 如果不想重写Thread类的run()方法外的其他方法,最好还是简单的
    实现Runnable接口(推荐)

11、线程的状态

  • 准备运行状态:ready to run
  • 运行状态:running
  • 暂停状态:suspended 运行中的线程可以暂停,暂停的线程可以重新启动
  • 阻塞状态:blocked 线程在等待其他资源时被阻塞

    (这个状态和视频播放器的操作非常类似,: )
   
    注意:线程在任何时候都能被终止,一旦终止就不能被重新激活
   
12、启动多个线程

   

/**
     * 改进的MyThread线程类(改为自启动线程)
     */
    public class MyThread implements Runnable {
       
        private Thread t;//线程对象
        public Thread getT() {
            return t;
        }
        /**构造方法*/
        public MyThread(String threadName){           
            //创建线程对象
            this.t = new Thread(this, threadName);
            System.out.println("创建子线程:" + threadName);
            //启动线程
            this.t.start();
        }
       
        /**
         * 功能:线程入口方法
         */
        public void run() {
           
            Thread t = Thread.currentThread();
            try {
               
                //打印数字1 ~ 5,间隔1秒
                for(int i = 1; i <= 5; i++){
                    System.out.println(t.getName() + " 打印:" + i);
                    //休眠1秒
                    Thread.sleep(1000);
                }               
            } catch (InterruptedException e) {
                System.out.println("子线程中断!");
            }
           
            System.out.println("子线程结束!");           
        }
    }
   
    /**
     * 多线程测试类
     */
    public class TestMyThread {
        public static void main(String[] args) {
           
            //创建线程对象1
            MyThread t1 = new MyThread("子线程1");
           
            //创建线程对象2
            MyThread t2 = new MyThread("子线程2");
           
            try {               
                //主线程打印数字1 ~ 5,间隔1秒
                for(int i = 1; i <= 5; i++){
                    System.out.println("主线程打印:" + i);
                    //休眠1秒
                    Thread.sleep(1000);
                }
               
            } catch (InterruptedException e) {
                System.out.println("主线程中断!");
            }           
            System.out.println("主线程结束!");
        }
    }

 

13、使用isAlive()join()

    问题: 主线程一般要最后结束,之前的示例中是通过在main方法中加入sleep()
    使主线程休眠足够长的时间以确保主线程最后结束,这个解决方式合理吗?怎样
    才能知道子线程是否终止?或者说怎样才能保证主线程最后结束?

    答案: 有两种方式可以确定一个线程是否结束:
    1)在线程中调用isAlive(),这个方法由Thread定义,如果它调用的线程仍在运行,
         返回true,否则返回false
    2)使用join()方法来等待另一个线程的结束,该方法一直等待直到它调用的线程终止

14、isAlive()和jion()示例

    尝试运行以下代码并观察主线程是否最后结束:

   

public static void main(String[] args) {
        MyThread t1 = new MyThread("子线程1"); // 创建线程1
        MyThread t2 = new MyThread("子线程2"); // 创建线程2
        MyThread t3 = new MyThread("子线程3"); // 创建线程3

            //显示线程是否运行
        System.out.println("子线程1是否运行:" + t1.getT().isAlive());
        System.out.println("子线程2是否运行:" + t2.getT().isAlive());
        System.out.println("子线程3是否运行:" + t3.getT().isAlive());
        // 主线程等待子线程结束
        try {
            System.out.println("等待子线程结束…");
            t1.getT().join(); // 等待t1线程结束
            t2.getT().join(); // 等待t2线程结束
            t3.getT().join(); // 等待t3线程结束
        } catch (InterruptedException e) {
            System.out.println("主线程中断!");
        }
        //显示线程是否运行
        System.out.println("子线程1是否运行:" + t1.getT().isAlive());
        System.out.println("子线程2是否运行:" + t2.getT().isAlive());
        System.out.println("子线程3是否运行:" + t3.getT().isAlive());
        System.out.println("主线程执行结束!");
    }

 


15、线程优先级概述

    Java给每个线程分配一个优先级,以决定哪个线程可以优先分配CPU时间
    优先级是一个整数,用于指定线程的相对优先程度
    优先级可以决定什么时候从一个运行中的线程切换到另一个线程,切换规则如下:

  •   一个线程自愿释放控制(放弃、睡眠或者阻塞),所有其他线
      程被检查,高优先级线程被分配CPU时间
  •   一个线程可以被另一个高优先级线程抢占资源,称为抢占式多任务

    注意:具有同一优先级的线程竞争CPU时间,不同操作系统的处理方式上存在差别

16、线程优先级设置

  • 线程调度器使用线程优先级以决定什么时候允许运行
  • 理论上高优先级的线程将比低优先级的线程得到更多CPU时间
  • 低优先级线程在运行时,高优先级的线程会抢占低优先级线程的执行权
  • 设置线程优先级,使用setPriority()方法:

    final void setPriority(int level);
    参数level为线程的优先级 ,其值在1 ~ 10 之间


    Thread类提供了如下常量方便优先级的设置
    Thread.MIN_PRIORITY == 1
    Thread.MAX_PRIORITY == 10
    Thread.NORM_PRIORITY == 5


17、线程优先级示例

   

/**
     * 功能:计数器线程
     */
    public class Clicker implements Runnable {
       
        private int click = 0;//计数值        
        private Thread t;//线程对象        
        private volatile boolean running = true;//运行开关
       
        public int getClick() {
            return click;
        }       
        public Thread getT() {
            return t;
        }       
        /**构造方法,参数为优先级*/
        public Clicker(int priority){
            this.t = new Thread(this);
            this.t.setPriority(priority);//设置线程优先级
        }
       
        public void run() {           
            while(this.running){               
                this.click++;//计数器累加
            }
        }
       
        public void start(){
            this.t.start();//启动线程
        }       
        public void stop(){
            this.running = false;//结束线程
        }       
    }
   
    /**
     * 计数器线程测试类
     */
    public class TestClicker {
        public static void main(String[] args) {
          
            //创建线程,设置4种档次的优先级
            Clicker hi = new Clicker(Thread.NORM_PRIORITY + 2);
            Clicker hi1 = new Clicker(Thread.NORM_PRIORITY + 4);
            Clicker lo = new Clicker(Thread.NORM_PRIORITY - 2);
            Clicker lo1 = new Clicker(Thread.NORM_PRIORITY - 4);           
            //启动线程
            hi.start();
            hi1.start();
            lo.start();
            lo1.start();
           
            try {               
                Thread.sleep(2000);//休眠2秒                
                //结束线程
                hi.stop();
                hi1.stop();
                lo.stop();
                lo1.stop();
                //等待线程结束
                hi.getT().join();
                hi1.getT().join();
                lo.getT().join();
                lo1.getT().join();               
            } catch (InterruptedException e) {
                System.out.println("主线程中断!");
            }           
            //显示计数器值
            System.out.println("lo1计数器:" + lo1.getClick());
            System.out.println("lo计数器:" + lo.getClick());
            System.out.println("hi计数器:" + hi.getClick());
            System.out.println("hi1计数器:" + hi1.getClick());
            System.out.println("主线程结束!");           
        }
    }

 

18、总结

  • 进程与线程的区别?
  • 如何获取主线程?
  • 创建线程的两种方式?
  • 获知线程是否运行使用哪个方法?
  • 等待线程执行结束使用哪个方法?
  • 线程优先级的范围是什么?

 

 

 

3
1
分享到:
评论

相关推荐

    完整版java基础入门教程由浅入深讲解 Java语言编程基础 含辅助PPT资料 全套PPT课件 共15个章节.rar

    完整版java基础入门教程由浅入深讲解 Java语言编程基础 第13章 多线程(共50页).ppt 完整版java基础入门教程由浅入深讲解 Java语言编程基础 第14章 网络通信(共76页).ppt 完整版java基础入门教程由浅入深讲解 ...

    线程 JAVA java线程 java线程第3版 java线程第2版第3版合集

    电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关...第五章 Java线程编程的例子 第六章 Java线程调度 第七章 Java线程调度例子 第八章 和同步相关的高级主题 第九章 多处理器机器上的并行化 第十章 线程组

    Java多线程编程深入详解.docx

    在本章中,我们探讨了多线程编程的基础知识,包括进程和线程的概念、Java对多线程的支持、第一个多线程程序等。下一章,我们将深入探讨多线程编程的高级技术和实践经验。 多线程编程的应用 多线程编程广泛应用于...

    完整版java基础入门教程由浅入深讲解 Java语言编程基础 第01章 java编程简介(共32页).ppt

    在第一章Java编程简介中,我们学习了Java语言的历史和特点,了解到Java是由Sun公司的James Gosling等人在1990年代初期开发的,最初命名为Oak。随着互联网的发展,Java逐渐转向Web应用程序,并在1995年正式发布。Java...

    java网络编程第四版pdf

    第一章“基本网络概念”主要介绍了网络的基础知识,包括TCP/IP协议族、互联网的工作原理、IP地址和域名系统。这一章将引导读者理解网络通信的基本模型,为后续的网络编程打下坚实的基础。作者深入浅出地解释了网络...

    Java2.0网络多线程编程实例教程(光盘源代码)

    《Java2.0网络多线程编程实例教程》是一本由李荣贵等人编写的书籍,专注于Java2.0(即Java SE 2)平台下的网络编程和多线程技术。该书通过丰富的实例,旨在帮助读者深入理解和掌握这两项核心的Java开发技能。 在...

    Java实训 Java高级应用编程 第4章 多线程编程(共29页).ppt

    Java多线程编程是Java高级应用的重要...总之,Java的多线程编程涉及到的内容广泛,从基础的线程创建到复杂的同步策略,都需要深入理解和实践才能熟练掌握。通过学习这一章,开发者可以更好地设计和实现高效的并发程序。

    Java语言基础入门教程 Java开发编程基础课程 第14章 线程 共22页.pptx

    ### Java语言基础入门教程:第14章 线程 #### 课程概述 本章节主要介绍了Java中的线程概念及其实现方式。通过学习,读者可以了解到如何创建线程、理解多线程的基本原理以及如何控制线程的运行。 #### 1. 线程与多...

    《java基础入门》第三版 第一章作业.doc

    Java 基础入门第三版第一章作业 Java 是一种高级语言,它具有跨平台性、面向对象、简单等特点。Java 语言的基本结构由类、对象、继承、多态、封装等概念组成。在 Java 中,类是最小的程序单元,用于定义对象的行为...

    java 多线程设计模式 进程详解

    第一章 线程简介 Java术语 线程概述 为什么要使用线程? 总结 第二章 Java线程API 通过Thread类创建线程 使用Runable接口的线程 线程的生命周期 线程命名 访问线程 线程的启动、停止和连接 总结 第三章 同步技术...

    Thinking in Java 自学笔记——第一章 对象导论

    Thinking in Java 自学笔记——第一章 对象导论 本章节总结了面向对象程序设计(Object-oriented Programming, OOP)的基本概念和原则,以帮助读者更好地理解 Java 编程语言。以下是对标题、描述、标签和部分内容的...

    Java编程基础课件

    在这个Java编程基础课件中,我们将会探讨一系列关键知识点,包括Java语言的起源、特性、环境搭建,以及基本语法元素。 首先,Java起源于1995年,由Sun Microsystems的詹姆斯·高斯林(James Gosling)等人设计,现...

    张孝祥java就业培训教程第二章_Java 编程基础WORD版

    Java编程基础是学习Java开发的重要基石,而"张孝祥java就业培训教程第二章_Java 编程基础WORD版"正是这样一个专注于此领域的教程。张孝祥,作为一位知名的IT教育专家,他的教程通常深入浅出,适合初学者入门及进阶者...

    《Java基础入门(第3版)》(Java):课后答案-docx文档

    第一章介绍了Java的基础概念,如对象、面向对象、javac编译器、JVM以及JRE的作用。第二章讲解了Java编程基础,包括关键字(如"class")、注释类型(单行、多行和文档注释)、数据类型(如基本数据类型和引用数据类型...

    Java语言程序设计(理论基础部分)ppt

    1 第一章 Java语言概述(1) 2 第一章 Java语言概述(2) 3 第二章 Java基础 4 第三章 面向对象程序设计基础 5 第四章 图形用户界面设计 6 第五章 Java Swing基础 7 第六章 Java图形与图像处理 8 第七章 多线程与...

    JAVA实用教程第一章PPT

    Java 实用教程的第一章主要介绍了Java语言的基本概况,包括其诞生背景、学习的重要性、语言特点、与C/C++的关系以及Java的运行平台。这一章的知识点涵盖了Java的基础和核心概念,对于初学者来说是非常关键的。 1. *...

    java线程实战手册

    虽然这里只提供了第一章的内容,但这一章通常会涵盖基础理论和核心概念,对于初学者来说是非常宝贵的入门资料。 Java并发编程的核心在于理解线程的概念,线程是程序执行的最小单元,每个线程都有自己的程序计数器、...

    Java语言基础教程:第一章概述 PPT

    本教程的第一章将对Java语言进行概览,帮助初学者建立坚实的基础。 一、Java语言的特性 1. 面向对象:Java是一种面向对象的语言,支持类、对象、继承、封装和多态等概念,使得代码结构清晰,易于维护。 2. 可移植性...

    Java完美编程(第三版)

    这一章还可能涉及编写第一个"Hello, World!"程序,以及对变量、数据类型、运算符和控制流的基本介绍。 2. **Chapter03.pdf**:可能会深入讲解面向对象编程(OOP)概念,如类、对象、封装、继承和多态性。此外,还将...

Global site tag (gtag.js) - Google Analytics