Java线程(一)

来源:互联网 发布:java和c语言的区别知乎 编辑:程序博客网 时间:2024/06/05 04:16

在Java语言提供了非常优秀的多线程支持,程序可以通过非常简单的方式来启动多线程。(本篇博客参考相关书籍和自己所知道写出线程的知识点)
进程与线程
几乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。
多线程则扩展了多进程的概念,使得同一个进行可以同时并发处理多个任务。线程(Thread)也被称作轻量级进程(Ligheweight Process),线程是进程的执行单元。就象进程在操作系统中的地位一样,线程在程序中是独立的、并发的执行流。当进程被初始化后,主线程就被创建了。对于绝大多数的应用程序来说,通常仅要求有一个主线程,但我们也可以在该进程内创建多条顺序执行流,这些顺序执行流就是线程,每条线程也是互相独立的。
线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程不再拥有系统资源,它与父进程的其它线程共享该进程所拥有的全部资源。因为多个线程共享父进程里的全部资源,因此编程更加方便;但必须更加小心,我们必须确保线程不会妨碍同一进程里的其它线程。
线程可以完成一定的任务,可与其他线程共享父进程中的共享变量及部分环境、相互之间协同来完成进程所要完成的任务。
简而言之:一个程序运行后至少有一个进程,一个进程里可以包含多个线程,但至少包含一个线程。
多线程编程的优势
1)进程间不能共享内存,但线程之间共享内存非常容易。
2)系统创建进程需要为该进程重新分配系统资源,但创建线程则代价小得多,因此使用多线程来实现多任务并发比多进程的效率高。
3) Java语言内置的多线程功能支持,而不是单纯地作为底层操作系统的调度方式,从而简化了Java的多线程编程。


对线程有个大概了解后,接下来就是要知道怎么创建和启动线程,创建线程有两种方式:

1.继承Thread类
步骤:
(1)定义类继承Thread
(2)复写Thread类中的run方法
目的:将自定义的代码存储在run方法中,让线程运行。
(3)调用线程的start方法,该方法有两个作用:启动线程,调用run方法。
2、创建线程的第二种方式:实现Runnable接口
步骤:
*(1)定义类实现Runnable接口
将线程要运行的代码存放在run方法中
(2)覆盖Runnable接口中的run方法
(3)通过Thread类建立线程对象
(4)将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
因为,自定义的run方法所属的对象是Runnable接口的子类对象,所以要让线程去指定对象的run方法,就必须明确run方法所属对象。
(5)调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
下列用代码演示:
第一种方式:

//通过继承Thread类来创建线程类public class FirstThread extends Thread{    //重写run()方法,run()方法的方法体就是线程执行体    public void run()    {        for(int i = 0; i < 100; i++)        {            //当线程类继承Thread类时,直接使用this即可获取当前线程            //Thread对象的getName()返回当前线程的名字            //因此可以直接使用调用getName()方法返回当前线程的名字            System.out.println(getName()+" "+i);        }    }    public static void main(String[] args) {        // TODO Auto-generated method stub        for(int i = 0; i < 100; i++)        {            System.out.println(Thread.currentThread().getName()+" "+i);            if(i==20)            {                new FirstThread().start();//创建并启动第一个线程                new FirstThread().start();//创建并启动第二个线程            }        }    }}

运行结果:
这里写图片描述
第二种方式:

public class SecondThread implements Runnable{    @Override    public void run() {        // TODO Auto-generated method stub        for(int i = 0; i < 100; i++)        {            //当线程类实现Runnable接口时            //如果想获取当前线程,只能用Thread.currentThread()方法            System.out.println(Thread.currentThread().getName()+" "+ i);        }    }    public static void main(String[] args) {        // TODO Auto-generated method stub        for(int i = 0; i < 100; i++)        {            System.out.println(Thread.currentThread().getName()+" "+ i);            if(i == 20)            {                SecondThread st = new SecondThread();                //通过new Thread(target,name)方法创建新线程                new Thread(st,"新线程1").start();                new Thread(st,"新线程2").start();            }        }       }}

运行结果:
这里写图片描述
实现方式和继承方式的区别:
实现方式好处:避免了单继承的局限性,在定义线程时,建议使用实现方式。
继承Thread:线程代码存放在Thread子类run方法中,实现Runnable,线程代码存放在接口的run方法中。
运行程序中,我们会发现运行结果每次都不同,因为多个线程都获取cpu的执行权,cpu执行到谁,谁就执行,在某一个时刻,只能有一个程序在运行(多核除外),cpu在做着快速的切换,以达到看上去是同时运行的效果,我们可以形象的把多线程的运行行为看成在互相抢夺cpu的执行权,这就是多线程的一个特性:随机性,谁抢到,谁执行,至于执行多长,cpu说了算。

0 0