Java多线程(二)- 如何构造一个线程?

版权声明:写文章辛苦,请不要复制粘贴,如果要,请注明来处 https://blog.csdn.net/u012627861/article/details/82904599

首先要明白startrun这两个方法。start方法意为启动一个线程,并不是立马执行这个线程,而是表示这个线程CPU可以去处理了。当CPU去处理这个线程的时候,运行是run方法中的代码。明白以后可以看下面的几个构造线程的方式。

第一种方式:通过Thread无参构造,构造一个什么也不干的线程

public static void main(String[] args){
	// 创建一个线程对象
	Thread t = new Thread(); 
	// 调用start方法启动线程,让线程加入CPU处理队列中,并不是立马执行
	t.start(); 
}

这样子就创建并且启动了一个线程,但这个线程什么也没干。我们可以查看Thread的源代码,看看里头的run方法实现。如下:

/* What will be run. */
private Runnable target;

@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

默认情况下,target为null,当我们没有覆盖Thread的run方法并且也没有给target赋值时,就是一个什么也不干的线程。

第二种方式:通过Thread(Runnable)构造一个“能做事”的线程

public static void main(String[] args){
	Thread t = new Thread(new Runnable(){
		public void run(){
			System.out.println("Thread t");
		}
	});
	t.start();
	System.out.println("Thread main");
}

这样子也创建了一个线程并且启动了。我们创建了一个Runnable接口匿名实现类,通过Thread(Runnable)构造,给Thread对象的target属性赋值。main方法执行后,结果有两种情况。
Case 1:

Thread main
Thread t

Case 2:

Thread t
Thread main

大部分情况肯定是第一种。为什么?后面再说。

第三种方式:通过继承Thread类,统一对业务进行处理

1、编写一个类,继承Thread类。这里假设为上面拍卖场景中的“创建出价记录”线程

public class CreateRecordThread extends Thread{
	// 覆盖run方法
	@Override
	public void run(){
		// 业务代码,省略
	}
}

2、在主线程中创建CreateRecordThread对象并启动

public static void main(String[] args){
	Thread t = new CreateRecordThread();
	t.start();
}

为什么要这么写?通过第二种方式不是也可以做到吗?原因是如果我们有一个业务需要总是被开启多线程去处理,那么采用第二种方式,这套业务代码可能会出现在多个地方,出现重复代码,维护起来就不方便了。这种方式则可以直接使用对应的线程类来执行业务代码。当然如果只是某一个地方需要用到,完全可以采用第二种方式去做。

第四种方式:新增业务处理类实现Runnable接口,将业务和线程分离

1、编写一个类,实现Runnable接口

public class CreateRecordRunnable implements Runnable{
	public void run(){
		// 业务代码,省略
	}
}

2、创建线程,运行业务代码

public static void main(String[] args){
	Runnable crt = new CreateRecordRunnable();
	Thread t = new Thread(crt);
	t.start();
}

这么写和第三种写法有什么区别?相对第三种有什么优势?

个人建议(仅供参考)

区别就不说了,一个是类一个是接口,扩展方式不一样。但都可以方便的进行扩展。创建出来的对象不一样,一个是线程类,一个是业务类
“优势”,其实不能说Runnable相对Thread有什么“优势”,但我们从代码的合理性去思考。假设我们有一大堆的业务需要开启一个或者多个线程去做,我们可以继承Thread,把业务方法写在run里头。如果代码量很大,我们可以编写多个private方法在run方法中调用,也可以新建一个父类继承Thread,提供通用方法给子类调用。我们可以知道,我们的业务处理类,居然是一个线程类。比如说发送邮件的类,比如说发送短信的类,这些类成为了一个线程对象,这并不合理,我们的业务处理对象为什么是一个线程类?我们更希望这些业务处理类是“一个可以被多线程运行的类”,而非本身就是一个线程。所以,本人总结也仅限本人总结:如果你要用继承Thread的方式,那么还是改为用实现Runnable的方式吧,这样对象的划分会合情合理一些。

(完)

猜你喜欢

转载自blog.csdn.net/u012627861/article/details/82904599