java是支持多线程开发,也是为数不多支持多线程开发的语言之一
进程是在操作系统上的划分,线程是在进程上的划分
线程是在进程基础上划分的更小的程序单元,线程是在进程基础上创建的,所以线程依赖于进程。其启动速度比进程快,所以当使用多线程进行并发处理的时候,其执行的性能更好
Thread类实现多线程
一个小Demo
class MyThread extends Thread{
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
super.run();
for (int i = 0; i < 5; i++) {
System.out.println(this.name + "运行, i = " + i);
}
}
}
start()方法和run()方法启动的区别?
多线程要执行的功能都应该在run()方法中进行定义。run()方法不能被直接调用,因为牵扯到操作系统资源调动问题,所以必须使用start方法。
使用start()方法和直接调用run()方法的区别:
(1)使用run()方法:
(2)使用start()
由图可见,调用start()方法才是实现了多线程并发处理。虽然调用了start()方法,但是执行的是run()方法内的语句,并且所有的线程对象都是交替执行的。
每一个线程的对象只能启动一次,如果重复启动,会抛出IllegalThreadStateException异常
为什么不使用run(),而使用start()?
线程的启动及运行关系到操作系统的资源管理问题
在不同的操作系统中,资源调配有不同的算法
而java是一种支持多平台编程的语言,其class文件在JVM上执行
start()方法中调用了**start0()**方法,但是start0方法只有方法名,没有方法体,其类型为native ,底层不是用java编写的,它是属于操作系统的一个具体函数,在java程序中只需要调用它们就好了,也就是说,不同的操作系统中,start0不一样,因此我们要使用start()方法寻找合适的start0(),从而使java程序适应平台
实现多线程
虽然可以通过Thread实现多进程,但是在java里面局限于单继承,所以有第二种多线程实现方法:实现Runnable接口。
通过实现接口,解决单继承问题,但此时问题就来了,不继承Thread类,就无法调用start()方法,就不能找到操作系统所对应的start0()方法。
为了解决这个问题,Thread类提供了一个构造方法,参数类型正是Runnable。
因此我们可以利用有参构造间接的创建Thread实例化对象,从而实现多线程
代码:
class MyThread implements Runnable{
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(this.name + "运行, i = " + i);
}
}
}
public class Pro {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyThread("线程1"));
Thread thread2 = new Thread(new MyThread("线程2"));
Thread thread3 = new Thread(new MyThread("线程3"));
thread1.start();
thread2.start();
thread3.start();
}
}
执行结果:
克服单继承局限,成功实现多线程
从JDK1.8 开始,可以用Lambda表达式实现多线程定义
public class Pro {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
String name = "线程对象" + (i + 1);
new Thread(()-> {
for (int j = 0; j < 10; j++) {
System.out.println(name + "运行, i = " + j);
}
}).start();
}
}
}
执行结果:
在实际开发中,优先选择Runnable进行多线程开发,并且通过Thread对象启动。