Java多线程的基本概述以及创建
学习笔记,欢迎指导。
△多线程概念
→进程:为了能够说清线程,首先要搞清楚进程概念。进程就是一个正在运行中的程序,这样理解:一个程序(或者说是一个软件)被装进了设备之后,它仅仅是一段静态代码,当他被运行起来时,就称作进程。所以说进程就是正在运行的程序,或者说是正在运行着的那个软件。
→线程:线程是比进程更小得控制单元,在早期的计算机中,进程是资源分配和内存调度的最小单位。后来,提出了比进程更加小的控制单元:线程。在现在的计算机中,进程作为资源分配单元,线程作为任务调度单元。每个线程都控制着进程中的一个任务(即软件的一个任务)。
→多线程:多个线程在控制着一个进程(一个程序)便称之为多线程了。打个比喻:比如网站售票系统,每个线程都对应着一个买票用户(每个线程都为一个用户服务)。
如果你想知道关于线程进程准确概念,你得翻阅操作系统相关书籍,我这只是粗略介绍。
△多线程意义:多线程使单个程序里的多个任务可以同时进行,比如响应用户操作与进行数据的运算可以同时进行(一个进程里的两个任务)。多线程最大程度地利用CPU的资源。
△Java里面创建线程两个方式
→继承Thread:自定义类继承Thread类,覆写里面的run方法,在run方法里面写入你想在线程里做的事情。
→实现Runnable接口(这个方式其实是有两个方法实现):
(1)可以向Thread构造方法直接传入”Runnable”实例(就是在给构造器传实参那时,直接new一个Runnable实例),同时重写Runnalble里面的run()方法。
(2)自己写一个类实现Runnable接口,然后重写run()方法。在创建Thread的时候,传入自己那个类的实例。
第一个方法的示例代码
以下代码共有两个自定义类,分别是两类线程的创建方式
package mythread;
public class MyThread {
/**
* @param args
*
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new MyThread01().start();//通过调用start方法来启动线程
new Thread(new MyThread02()).start();
}
}
//创建线程的第一个方式
class MyThread01 extends Thread{//自定义类继承Thread
public void run() {//覆写run()方法
while(true){
System.out.println("--1号线程--");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//catch
}//while
}//run
}
//创建线程的第二个方式
class MyThread02 implements Runnable{
public void run() {
// TODO Auto-generated method stub
while(true){
System.out.println("--2号线程--");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//catch
}//while
}//run
}//MyThread02
→注:
(1)两个启动线程的方式相比较:
1>实现方式的好处:避免了单继承的局限性(Java支持多实现但不支持多继承)。
2>由于第一点,所以在创建线程那个时候就建议使用第二个方式。
3>运行代码所处位置:继承方式线程代码存放在Thread子类的run()方法里面;实现接口方式线程代码,存放在接口的子类的run()方法里面。
(2)一个Thread实例就是一个线程,但是,线程的创建和启动是两回事,创建一个Thread实例就创建了一个线程,但是,创建了线程不代表你就启动他了,不要创建了线程就不管他了,还要记得start()方法启动。
(3)new Thread().start();与new Thread().run();是不同的,有人会想,既然线程的具体操作是run()方法里的那段代码,那为什么还要调用start方法,首先,start的意思是:启动一个新的线程,并且新线程执行的将是run()方法里的代码。其次,run()仅仅只是封装了一段代码的方法,这个方法本身不会启动一个新的线程。如果仅仅是调用了run方法,那里面的所有代码都运行在主线程里,不会新开一个线程。现在我们说说三样东西间的关系:每一个Thread的实例(或者他的子类实例)就是一个新的线程(一个被创建但没有被启动的线程)、run()方法封装了线程所要执行的操作、start()方法正式启动一个线程,并且指定该线程的运行代码,就是run()方法里面的代码。