一、 进程
是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。
比如在Windows系统中,一个运行的exe就是一个进程。
二、线程
是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。
线程总是属于某个进程,进程中的多个线程共享进程的内存。“同时”执行是人的感觉,在线程之间实际上轮换执行。
现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。
创建多线程程序的方法及步骤:
方法一:用 Thread 类创建线程
1) 一写个类,继承自 Thread 类
2) 重写run方法 //这个方法里放的变是要执行的内容
3) new 这个自定义的Thread 类
4) 调用start方法,启动这个线程 (start 方法有两个作用 ,一个是开启线程,一个是调用run方法)
public class Test12 {
public static void main(String[] args) {
ThreadDemo t = new ThreadDemo();
t.start();// 啓動
ThreadDemo t2 = new ThreadDemo();
t2.start();
ThreadDemo t3 = new ThreadDemo();
t3.start();
for (int i = 0; i < 20; i++) {
System.out.println("线程" + Thread.currentThread().getName() + "正在运行");
}
}
}
class ThreadDemo extends Thread {
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("线程" + Thread.currentThread().getName() + "正在运行");
}
}
}
打印结果:
线程Thread-0正在运行
线程Thread-0正在运行
线程Thread-0正在运行
线程Thread-2正在运行
线程main正在运行
线程Thread-1正在运行
线程Thread-1正在运行
线程Thread-1正在运行
线程main正在运行
线程Thread-2正在运行
线程Thread-0正在运行
线程Thread-2正在运行
。。。。。。。。。。。
下面还有输出省略了
要点总结:
要将一段代码放在一个新的线程上运行,这段代码应该放在一个类的 run 函数中, 并且,ran函数所在的类是Thread类的子类
倒过来说,我们要实现多线程,必须编写一个继承了Threa类的的子类,并重写其run方法
启动一个线程,我们不是调用Thread子类对象的run方法,而是调用Thread子类对象的start 方法( 从Thread类继承到的),该方法将
产生一个新的线程 并在该线程上运行子类对象中的run方法
由于线程的代码段放在run 方法中,那么该方法执行完后,线程就结束了
public class Test {
public static void main(String[] args) throws InterruptedException {
ThreadDemo t=new ThreadDemo();
t.start();
while(true){
System.out.println("这是线程一输出的内容");
Thread.sleep(10);
}
}
}
class ThreadDemo extends Thread{
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println("这是线程二输出的内容");
}
}
}
//例子,创建三个线程,和主线程同时运行
public class Test2 {
public static void main(String[] args) {
MyThread t1=new MyThread();
t1.start();
MyThread t2=new MyThread();
t2.start();
MyThread t3=new MyThread();
t3.start();
for (int i = 0; i < 200; i++) {
System.out.println("主线程"+Thread.currentThread().getName()+"正在运行");
}
}
}
方法二:使用Runnable接口实现多线程
1)自定义一个类,implements Runnable接口
2)重写run方法
3)new出来这个自定的类//该类对象会作为Thread类构造函数的参数
4)new出Thread类
5)调用start方法
代码演示:
//使用Runnable实现多线程
//注意:在调用的时候与Thread的不同。。。
public class Test13 {
public static void main(String[] arg) {
/*
* 注意:
*1.下面用到的是Runnable接口
*2.并没有继承Thread,就不能直接用.start()方法
*
* 解决办法:
*1.MyThread對象依然要被创建;
*2.创建Thread对象;
*3.将MyThread创建的对象作为Thread构造函数的参数,传入
* 4.即可调用.start();方法了
*/
MyThread m = new MyThread();// 此时,m好像没参与,把它传入下一行Thread();中
Thread t = new Thread(m);
t.start();
for (int i = 0; i < 10; i++) {
System.out.println("--------》");
}
}
}
// 实现Runnable接口
class MyThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 14; i++) {
System.out.println("(--------");
}
}
}
继承Thread类创建线程和实现Runnable接口创建线程的区别
使用 Runnable 接口创建多线程
1.适合多个相同的程序代码去处理同一资源的情况 把虚拟CPU (线程)同程序的代码 数据有效分离,较好的体现了面象对象
2.可以避免java单继承带来的局限
例如:当我们将已经继承了某类的一个类的子类放入多线程中,由于不能同时继承两个类,所以这什么情况下,不能采用继承Thread的方式,只好通过实现Ruanable。.当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口类的实例.事实上,几乎所有的多线程都可以用Runnable接口方式
代码演示:(这个代码有有误,