`
神绮_H_亚里亚
  • 浏览: 9649 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

线程(上)

阅读更多

1. 什么是线程 

        传统的程序设计语言同一时刻只能执行单任务操作,效率非常低,如果网络程序在接收数据时发生阻塞,只能等到程序接收数据之后才能继续运行。随着 Internet 的飞速发展,这种单任务运行的状况越来越不被接受。如果网络接收数据阻塞,后台服务程序就会一直处于等待状态而不能继续任何操作。这种阻塞情况经常发生,这时的 CPU资源完全处于闲置状态。

         多线程实现后台服务程序可以同时处理多个任务,并不发生阻塞现象。多线程是 Java 语言的一个很重要的特征。多线程程序设计最大的特点就是能够提高程序执行效率和处理速度。Java 程序可同时并行运行多个相对独立的线程。例如创建一个线程来接收数据,另一个线程发送数据,既使发送线程在接收数据时被阻塞,接受数据线程仍然可以运行。 线程(Thread)是控制线程(Thread of Control)的缩写,它是具有一定顺序的指令序列(即所编写的程序代码)、存放方法中定义局部变量的栈和一些共享数据。线程是相互独立的,每个方法的局部变量和其他线程的局部变量是分开的,因此,任何线程都不能访问除自身之外的其他线程的局部变量。如果两个线程同时访问同一个方法,那每个线程将各自得到此方法的一个拷贝。 

       Java 提供的多线程机制使一个程序可同时执行多个任务。线程有时也被称为小进程,它是从一个大进程里分离出来的小的独立的线程。由于实现了多线程技术,Java 显得更健壮。多线程带来的好处是更好的交互性能和实时控制性能。多线程是强大而灵巧的编程工具,但要用好它却不是件容易的事。在多线程编程中,每个线程都通过代码实现线程的行为,并将数据供给代码操作。编码和数据有时是相当独立的,可分别向线程提供。多个线程可以同时处理同一代码和同一数据,不同的线程也可以处理各自不同的编码和数据。 

2 .创建线程方法

       Java程序都是声明一个公共类,并在类内实现一个 main 方法。事实上,这些程序就是一个单线程程序。当它执行完main 方法的程序后,线程正好退出,程序同时结束运行。

 

public class OnlyThread {  
    public static void main(String args[]) {  
        run(); // 调用静态run()方法  
    }  
  
    /** 
     * 实现run()方法 
     */  
    public static void run() {  
	        // 循环计算输出的*数目  
	        for (int count = 1, row = 1; row < 10; row++, count++) {  
	            for (int i = 0; i < count; i++) { // 循环输出指定的count数目的*  
	                System.out.print('*');   
	            }  
	            System.out.println();  
	        }  
	    }  
	}  

 

 

  只是建立了一个单一线程并执行的普通小程序,并没有涉及到多线程的概念。

       Java程序中,有两种方法创建线程:
       
一是对 Thread 类进行派生并覆盖 run方法;

        二是通过实现 runnable接口创建。 

3. Thread 创建线程

     在程序中创建新的线程的方法之一是继承 Thread 类,并通过 Thread子类声明线程对象。继承Thread 类并覆盖 Thread类的 run 方法完成线程类的声明,通过new创建派生线程类的线程对象。run 中的代码实现了线程的行为。 

 

      java.lang.Thread 类是一个通用的线程类,由于默认情况下 run 方法是空的,直接通过 Thread类实例化的线程对象不能完成任何事,所以可以通过派生 Thread 类,并用具体程序代码覆盖Thread 类中的 run 方法,实现具有各种不同功能的线程类。

 

      1) Thread 创建线程步骤: 

 

     1)创建一个新的线程类,继承 Thread 类并覆盖 Thread 类的 run()方法。 

 

	class ThreadType extends Thread{   
	     public void run(){   
	         ……   
	     }   
	}   

 

 

2)创建一个线程类的对象,创建方法与一般对象的创建相同,使用关键字new完成。

 

	ThreadType  tt = new ThreadType();  

 (3)启动新线程对象,调用 start()方法。

 

 

	tt.start();

 (4)线程自己调用 run()方法。

 

 

void run(); 

 

 

 

  2) Thread创建一个线程

 

     

class ThreadDemo1 extends Thread {  
    ThreadDemo1() {  
    }  
  
    // 声明ThreadDemo1带参数的构造方法  
    ThreadDemo1(String szName) {  
        super(szName);  
    }  
  
	    // 重载run函数  
	    public void run() {  
	        for (int count = 1, row = 1; row < 10; row++, count++) {  
	            for (int i = 0; i < count; i++) {// 循环输出指定的count数目的*  
	                System.out.print('*');  
	            }  
	            System.out.println();  
	        }  
	    }  
	  
	    public static void main(String argv[]) {  
	        ThreadDemo1 td = new ThreadDemo1(); // 创建,并初始化ThreadDemo1类型对象td  
	        td.start(); // 调用start()方法执行一个新的线程  
	    }  
	}  

 

 

 

  OnlyThread.java程序与程序ThreadDemo1.java表面上看运行结果相同,但是仔细对照会发现,程序OnlyThread.java中对 run方法的调用在程序ThreadDemo1.java中变成了对 start 方法的调用,并且程序ThreadDemo1.java确派生 Thread类,创建新的线程类。 

 

 3) Thread创建多个线程

//产生三个新的线程 
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

public class ThreadDemo2 extends Thread {  
    // 声明无参数,空构造方法  
    ThreadDemo2() {  
    }  
  
    // 声明带有字符串参数的构造方法  
    ThreadDemo2(String szName) {  
        super(szName); // 调用父类的构造方法  
    }  
	  
	    // 重载run函数  
	    public void run() {  
	        for (int count = 1, row = 1; row < 10; row++, count++) {  
	            for (int i = 0; i < count; i++) {// 循环输出指定的count数目的*  
	                System.out.print('*');  
	            }  
	            System.out.println();  
	        }  
	    }  
	  
	    public static void main(String argv[]) {  
	        ThreadDemo2 td1 = new ThreadDemo2(); // 创建,并初始化ThreadDemo2类型对象td1  
	        ThreadDemo2 td2 = new ThreadDemo2(); // 创建,并初始化ThreadDemo2类型对象td2  
	        ThreadDemo2 td3 = new ThreadDemo2(); // 创建,并初始化ThreadDemo2类型对象td3  
	        td1.start(); // 启动线程td1  
	        td2.start(); // 启动线程td2  
	        td3.start(); // 启动线程td3  
	    }  
	}  

 创建了 3 个线程 td1td2td3,它们分别执行自己的 run方法。在实际中运行的结果并不是想要的直角三角形,而是一些乱七八糟的 “*” 行,长短并没有一定的规律,这是因为线程并没有按照程序中调用的顺序来执行,而是产生了多个线程赛跑现象。 运行结果:

 

 注意:Java线程并不能按调用顺序执行,而是并行执行的单独代码。如果要想得到完整的直角三角形,需要在执行一个线程之前,判断程序前面的线程是否终止,如果已经终止,再来调用该线程。

 

 

4. Runnable 接口创建线程 

 

        通过实现 Runnable 接口的方法是创建线程类的第二种方法。利用实现 Runnable 接口来创建线程的方法可以解决 Java 语言不支持的多重继承问题                Runnable 接口提供了 run()方法的原型,因此创建新的线程类时,只要实现此接口,即只要特定的程序代码实现Runnable接口中的 run()方法,就可完成新线程类的运行。

 

      扩展Thread类创建线程的方式,适合编写简单的应用程序代码,而实现Runnable接口创建线程,能够避免Java单继承的局限,适合同一代码的多线程处理同一资源的情况,代码具有良好的一致性,是更符合面向对象思想的设计方式。

 

     1) Runnable 创建线程步骤 

   1)创建一个实现 Runnable 接口的类,并且在这个类中重写 run 方法。

 

 

	class ThreadType implements Runnable{   
	     public void run(){   
	         ……   
	     }   
	}   

 2)使用关键字 new新建一个 ThreadType 的实例。

Runnable rb = new ThreadType ();   

 3)通过 Runnable 的实例创建一个线程对象,在创建线程对象时,调用的构造函数是new Thread(ThreadType),它用 ThreadType 中实现的 run()方法作为新线程对象的 run()方法。 

 

	Thread td = new Thread(rb);  

 4)通过调用 ThreadType 对象的 start()方法启动线程运行。 

	td.start();   

  2) Runnable 创建线程

 

 

class ThreadDemo3 implements Runnable {  
       // 重载run函数  
       public void run() {  
           for (int count = 1, row = 1; row < 10; row++, count++){ // 循环计算输出的*数目  
               for (int i = 0; i < count; i++){ // 循环输出指定的count数目的*  
                   System.out.print('*');   
               }  
               System.out.println();   
           }  
     }  
   
     public static void main(String argv[]) {  
         Runnable rb = new ThreadDemo3(); // 创建,并初始化ThreadDemo3对象rb  
         Thread td = new Thread(rb); // 通过Thread创建线程  
         td.start(); // 启动线程td  
     }  
 }  

 

 

分享到:
评论

相关推荐

    易语言源码易语言线程上下文注入源码.rar

    易语言源码易语言线程上下文注入源码.rar 易语言源码易语言线程上下文注入源码.rar 易语言源码易语言线程上下文注入源码.rar 易语言源码易语言线程上下文注入源码.rar 易语言源码易语言线程上下文注入源码.rar ...

    C# 跨线程访问UI线程控件

    在C#中,由于使用线程和调用UI的线程属于两个不同的线程,如果在线程中直接设置UI元素的属性,此时就会出现跨线程错误。    下面介绍两种解决方案  第一种:使用控件自带的Invoke或者BeginInvoke方法。 Task....

    C#多线程编程 四个显示线程计算结果的函数

    从属线程需要随时将中间结果先是在主界面上,鉴于控件总是由主执行线程所有,从属线程... 应使用Control.BeginInvoke或Control.Invoke方法来调用主执行线程上的方法,从而使必须发生的跨线程边界的封送处理量减到最少。

    16丨多线程调优(下):如何优化多线程上下文切换?.html

    16丨多线程调优(下):如何优化多线程上下文切换?.html

    多线程不同步读写共享资源代码

    这听起来感觉挺好,因为一旦同步线程,将在同步线程上花去一定的CPU时间片. 这一切都是真的,但是,不同步线程的条件是:只开两个线程,读线程在写线程之后进行操作.满足这两个条件,就可以不用进行线程同步啦! 如何...

    易语言线程上下文注入源码-易语言

    易语言线程上下文注入源码

    c#Winform异步线程刷新UI

    使用开发工具为VS2013;.net:4.0 多线程异步刷新ui界面,实时获取任务进度并进行反馈。

    QT在子线程中调用定时器

    QT中在子线程中调用定时器 https://blog.csdn.net/wb175208/article/details/108476275

    C# 线程相关知识总结

    在该线程上可以创建其他线程。 图: 线程工作方式 多线程由内部线程调度程序管理,线程调度器通常是CLR委派给操作系统的函数。线程调度程序确保所有活动线程都被分配到合适的执行时间,线程在等待或阻止时 (例如...

    MFC多线程的创建,包括工作线程和用户界面线程

    《MFC多线程的创建,包括工作线程和用户界面线程》全面讲解MFC多线程的创建,界面多线程与工作者多线程,多线程的起源、继承与派生,两多线程之间的区别与相同点,定时器与多线程的关系与异同(定时器是定时优先抢占...

    JAVA单线程多线程

    单线程 单线程 单线程 单线程 单线程 单线程

    Java 多线程编程面试集锦20道问题解答Java多线程编程高难度面试题及解析

    您将了解线程安全、死锁、线程池、线程上下文切换、线程同步和互斥、volatile关键字、synchronized关键字等重要知识点。此外,还探讨了线程间通信、线程优先级、守护线程、线程组、可重入锁、线程局部变量等关键概念...

    MFC多线程 工作者线程 用户界面线程

    MFC多线程 工作者线程 用户界面线程

    基于SpringBoot和POI实现单线程和多线程导出Excel.zip

    基于SpringBoot和POI实现单线程和多线程导出Excel.zip基于SpringBoot和POI实现单线程和多线程导出Excel.zip基于SpringBoot和POI实现单线程和多线程导出Excel.zip基于SpringBoot和POI实现单线程和多线程导出Excel.zip...

    C#多线程笔记

    C#多线程笔记 每个窗体都有自己的都在不同的线程上运行,如果需要在窗体之间交互,就需要在线程之间交互。

    Qt5中两种线程操作的方法 demo代码

    作用:将某一个对象从当前的线程中推到另一个线程中,但是不能将其他线程的对象拉到当前线程上; 原理:其实是通过信号和槽的方式实现;将需要通过线程处理的代码放入到一个槽函数中; 注意:如果对象存在父对象 则...

    c_多线程 c_多线程

    c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程c_多线程...

    C#多线程 C#多线程

    多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程多线程

    php 多线程上下文中安全写文件实现代码

    提供一个php多线程上下文中安全写文件的实现方法。这个实现没有使用php 的file lock机制,使用的是临时文件机制。多线程中的各个线程都是对各自(每个线程独占一个)的临时文件写,然后再同步到原文件中。

    单线程与多线程的区别

    可以根据这个示例,更能了解到单线程与多线程的区别所在

Global site tag (gtag.js) - Google Analytics