欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java线程学习笔记(二):线程的创建

程序员文章站 2022-07-12 21:17:54
...

Java中创建线程有两种方式:

  • 需要从java.lang.Thread类派生出一个新的子类,并在子类中重写Thread类中的run方法
  • 需要实现java.lang.Runnable接口,并实现Runnable中的run方法

下面分别使用两种不同的方式,重写run方法,实现Java多线程操作

 

一、继承java.lang.Thread类

public class Hello extends Thread{
	
	public Hello(){}
	
	public Hello(String name) {
		this.name = name;
	}
	
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			//造成一定的等待时间,可根据个人电脑快慢调整数字大小
			for (int j = 0; j < 1000000; j++) ;
			System.out.println(name + "运行    " + i);
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		Thread h1 = new Hello("A");
		Thread h2 = new Hello("B");
		
		h1.run();
		h2.run();
		
		//用户观察主线程与子线程的执行标记
		System.out.println("程序执行结束!");
	}
	
	private String name;

}
执行结果 写道
A运行 0
A运行 1
A运行 2
... ...
A运行 98
A运行 99
B运行 0
B运行 1
B运行 2
... ...
B运行 98
B运行 99
程序执行结束!

 分析:当程序使用run方法的方式调用执行的时候,根据执行结果,可以清楚的看到,该代码在主线程启动后,顺序执行,即并无新的线程启动。

 

将上述代码中的run方法,替换为start方法,如下:

public static void main(String[] args) throws InterruptedException {
		Thread h1 = new Hello("A");
		Thread h2 = new Hello("B");
		
		h1.start();
		h2.start();
		
		//用户观察主线程与子线程的执行标记
		System.out.println("程序执行结束!");
	}

 

执行结果 写道
程序执行结束!
A运行 0
A运行 1
... ...
A运行 20
B运行 0
B运行 1
... ...
B运行 40
B运行 41
A运行 21
... ...
A运行 64
B运行 42
... ...
B运行 83
A运行 65
... ...
A运行 99
B运行 84
... ...
B运行 99

 分析:当程序使用start方法的方式调用执行的时候,根据执行结果,程序的主线程首先执行完毕,紧接着,由程序的其他两个线程A和B分别交替进行,也就是说,主线程、线程A和线程B为三个独立的线程,并且,线程A和线程B均由主线程创建启动。线程A和线程B均通过start方法间接调用Hello类中的run方法执行相应的操作,并且相互之间独立运行。(可多执行几次,每次执行的结果可能会不同)

 

二、实现java.lang.Runnable接口

public class Hello implements Runnable{
	
	public Hello(){}
	
	public Hello(String name) {
		this.name = name;
	}
	
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			//造成一定的等待时间
			for (int j = 0; j < 1000000; j++) ;
			System.out.println(name + "运行    " + i);
		}
	}
	
	public static void main(String[] args) throws InterruptedException {
		Hello h1 = new Hello("A");
		Hello h2 = new Hello("B");
		
		Thread t1 = new Thread(h1);
		Thread t2 = new Thread(h2);
		
		t1.run();
		t2.run();
		
		//用户观察主线程与子线程的执行标记
		System.out.println("程序执行结束!");
	}
	
	private String name;

}

 分析:如上代码所示,由继承java.lang.Thread类改为实现java.lang.Runnable接口,main方法中,启动线程的代码有所改变,其余执行run方法和start方法的执行结果,与继承java.lang.Thread类时,并无区别

 

三、两种方法创建线程的区别

  • Java中类仅支持单继承,也就是说定义一个新的类的时候,它只能扩展一个父类。因此,如果创建自定义线程类的时候是通过扩展java.lang.Thread实现的,那么自定义的类就不能再扩展其他类,也就是不能实现更复杂的功能。因此,如果自定义类必须扩展非java.lang.Thread的其它类那么就可以使用实现java.lang.Runnable接口的方式来自定义线程类,这样就可以避免由Java单继承所带来的局限性。
  • 使用实现java.lang.Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享。

四、小结

实现Runnable接口相对于扩展Thread类来说,具有无可比拟的优势。

  • 适合多个相同的程序代码的线程去处理同一个资源
  • 可以避免Java中单继承限制
  • 增加程序的健壮性,代码可以被多个线程共享,代码和数据独立,特别适合多个具有相同代码的线程去处理同一资源的情况

 

注:本文源自互联网,经过查阅网上资料整理而成,如涉及到他人整理的成果,在此表示感谢。由于涉及到的参考文章比较多,在此就不再一一列举。

本文是目前个人理解的结果,仅供参考,如后续发现问题,本人会进行相应的更正,也欢迎各位对Java线程感兴趣的朋友或者前辈进行指正。