1.1、使用多线程
一个进程在运行时至少会有1个线程在运行,线程会在后台执行;例如调用public static void main() 方法的线程就是如此,而且由JVM创建。
package test;
public class Test{
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
}
}
程序运行返回结果如下:
注意:
- 输出的main是名为main的线程,执行main() 方法中的代码。
- 输出的main和main() 方法无任何关系,仅名字相同。
1.2、多线程编程的两种实现方式
多线程编程的实现方式:
- 继承 Thread 类
- 实现 Runnable 接口
Thread 类的结构:
由源代码可以看出,Thread 类实现了 Runnable 接口,之间具备多态关系。
Thread 和 Runnable 实现多线程的区别(没有本质区别):
Thread | Runnable |
单继承 | 多继承(即多实现) |
继承 | 实现 |
1.3、继承Thread类
多线程的特性
- 线程调用随机性
- 线程随机性
- 执行 start() 方法的顺序与线程启动的顺序无关
线程调用随机性示例
package test.myThread
/**
* 创建一个自定义的线程类MyThread.java,
* 此类继承自Thread,
* 重写run方法
* 在run方法中,写线程要执行的任务
* @author admin
*/
public class MyThread extends Thread {
@Override
public void run(){
super.run();
System.out.println();
}
}
package test;
import com.myThread.MyThread;
/**
* 运行代码
* @author admin
*/
public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println("运行结束!");
}
}
运行结果如下:
结论:
- 由结果看出在使用多线程时,代码的运行结果与代码的执行顺序或调用顺序是无关的。
- 线程是一个子任务,CPU以不确定的方式,或者说是以随机的时间来调用线程中的run方法,所以先输出“运行结束!” 再输出“MyThread”。
线程随机性
package com.myThread;
/**
* 创建一个自定义的线程类MyThread.java,
* 此类继承自Thread,
* 重写run方法
* 在run方法中,写线程要执行的任务
* @author admin
*/
public class MyThread2 extends Thread{
@Override
public void run() {
try{
for(int i=0; i<10; i++) {
int time = (int) (Math.random() * 1000);
Thread.sleep(time);
System.out.println("run=" + Thread.currentThread().getName());
}
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
package test;
import com.myThread.MyThread2;
/**
* 运行代码
* @author admin
*/
public class Test2 {
public static void main(String[] args) {
MyThread2 myThread2 = new MyThread2();
myThread2.setName("myThread2");
myThread2.start();
try{
for(int i=0; i<10; i++) {
int time = (int) (Math.random() * 1000);
Thread.sleep(time);
System.out.println("main=" + Thread.currentThread().getName());
}
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
运行结果如下:
结论:
- CPU执行哪个线程具有不确定性,所以线程的调用是随机性的。
执行 start() 方法的顺序与线程启动的顺序无关
package com.myThread;
public class MyThread3 extends Thread{
private int i;
public MyThread3(int i) {
super();
this.i = i;
}
@Override
public void run() {
System.out.println(i);
}
}
package test;
import com.myThread.MyThread3;
/**
* 运行代码
* @author admin
*/
public class Test3 {
public static void main(String[] args) {
MyThread3 my1 = new MyThread3(1);
MyThread3 my2 = new MyThread3(2);
MyThread3 my3 = new MyThread3(3);
MyThread3 my4 = new MyThread3(4);
MyThread3 my5 = new MyThread3(5);
MyThread3 my6 = new MyThread3(6);
MyThread3 my7 = new MyThread3(7);
MyThread3 my8 = new MyThread3(8);
MyThread3 my9 = new MyThread3(9);
MyThread3 my10 = new MyThread3(10);
my1.start();
my2.start();
my3.start();
my4.start();
my5.start();
my6.start();
my7.start();
my8.start();
my9.start();
my10.start();
}
}
运行结果如下:
结论:
- 执行 start() 方法的顺序不代表线程启动的顺序。