多线程的创建方法

        所谓线程就是就是一个执行单元,而一个进程就是一个程序,简单来说,打开一个qq软件就是一个进程,同时打开一个微信,那就是两个进程。那么线程就是在一个轻量级进程,比如打开微信与A聊天是一个线程,与B聊天就是另一个线程。使用多线程的好处:

1.可以减少程序的响应时间。

2.与进程相比,线程的创建和切换开销更小。

3.使用多线程能够简化程序的结构,便于程序理解和维护。

        以下就是来说明线程的创建方法。

        首先,先说明本文说明的例子是学生有每个月存钱的习惯,这里举了Tom和Jack的例子,他俩其实互不干涉,谁先到银行谁先存,但是如果是一般地程序,则会等一个人完成所有操作,才会另一个人存,所以需要创建新的线程。下面是文中例子涉及的学生类。

package person;

public class Student {
	public int k=0;
	public int total;
	public int perMonth;
	public String name;
	public void saveMoney(Student s) {
		// TODO Auto-generated method stub
		
		try {
			Thread.sleep(1000);
		}
		catch(InterruptedException e) {
			e.printStackTrace();
		}
		s.k+=1;
		if(s.k>=12)
			System.out.println(s.name+"存储结束,总共存储了:"+s.total+"元");
		else
		{
			s.total=s.total+s.perMonth;
			System.out.println(s.name+"第"+k+"年总共拥有"+s.total+"元");
		}
	}

}

1.普通程序

        普通的情况便是不使用线程的情况,则是按顺序执行,只有前面的执行完之后才能执行后面的程序,具体代码如下所示:

 package waytobuildthread;

import person.Student;

public class GeneralTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student tom=new Student();
		Student jack=new Student();
		tom.total=1000;
		tom.perMonth=200;
		tom.name="Tom";
		jack.total=1500;
		jack.perMonth=100;
		jack.name="Jack";
		
		while(tom.k<12)
			tom.saveMoney(tom);
		
		while(jack.k<12)
			jack.saveMoney(jack);

	}

}

运行程序,得到结果如下:

Tom第1月总共拥有1200元
Tom第2月总共拥有1400元
Tom第3月总共拥有1600元
Tom第4月总共拥有1800元
Tom第5月总共拥有2000元
Tom第6月总共拥有2200元
Tom第7月总共拥有2400元
Tom第8月总共拥有2600元
Tom第9月总共拥有2800元
Tom第10月总共拥有3000元
Tom第11月总共拥有3200元
Tom存储结束,总共存储了:3200元
Jack第1月总共拥有1600元
Jack第2月总共拥有1700元
Jack第3月总共拥有1800元
Jack第4月总共拥有1900元
Jack第5月总共拥有2000元
Jack第6月总共拥有2100元
Jack第7月总共拥有2200元
Jack第8月总共拥有2300元
Jack第9月总共拥有2400元
Jack第10月总共拥有2500元
Jack第11月总共拥有2600元
Jack存储结束,总共存储了:2600元

        由上面的运行结果可以知道:只有等Tom12个月存完之后才输出Jack12个月存的过程。这样的过程显然不合理,因此需要引入多线程的概念,以下便是讲解几个创建多线程的方法。

2.继承Thread类

        Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且启动线程的唯一方法就是通过Thread类的start()方法。这过程中需要重写run()方法,当调用Thread类的start()方法时,只是使该线程变为可运行状态,而不是直接执行run()方法。以下是通过该方法实现本文示例的代码:

首先是创建线程

package waytobuildthread;
import person.Student;
public class ExtendsThread extends Thread {
	public Student s;
	public int total;
	public int m;
	public ExtendsThread(Student s)
	{
		this.s=s;
		
	}
	public void run()
	{
		while(s.k<12)
			s.saveMoney(s);
	}

}

然后测试线程:

package waytobuildthread;
import person.*;

public class ExtendsThreadTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student tom=new Student();
		Student jack=new Student();
		tom.total=1000;
		tom.perMonth=200;
		tom.name="Tom";
		jack.total=1500;
		jack.perMonth=100;
		jack.name="Jack";
		
		ExtendsThread thread1=new ExtendsThread(tom);
		thread1.start();
		ExtendsThread thread2=new ExtendsThread(jack);
		thread2.start();

	}

}

最后运行测试程序,得到如下结果:

Jack第1月总共拥有1600元
Tom第1月总共拥有1200元
Jack第2月总共拥有1700元
Tom第2月总共拥有1400元
Tom第3月总共拥有1600元
Jack第3月总共拥有1800元
Tom第4月总共拥有1800元
Jack第4月总共拥有1900元
Tom第5月总共拥有2000元
Jack第5月总共拥有2000元
Jack第6月总共拥有2100元
Tom第6月总共拥有2200元
Tom第7月总共拥有2400元
Jack第7月总共拥有2200元
Jack第8月总共拥有2300元
Tom第8月总共拥有2600元
Jack第9月总共拥有2400元
Tom第9月总共拥有2800元
Jack第10月总共拥有2500元
Tom第10月总共拥有3000元
Jack第11月总共拥有2600元
Tom第11月总共拥有3200元
Tom存储结束,总共存储了:3200元
Jack存储结束,总共存储了:2600元

        从上面的结果可以看出,使用多线程来执行该例,则更切实际,即谁先到银行谁先存钱,整个过程是同步的。

3.实现Runnable接口

        该方法主要三个步骤:1.实现Runnable接口,实现run()方法。2.创建Thread对象,用实现Runnable接口的对象作为参数实例化该Thread对象。3.调用Thread的start()方法。

实现接口:

package waytobuildthread;

import person.Student;

public class ImplementRunnable implements Runnable {
	public Student s;
	public int total;
	public int m;
	public ImplementRunnable(Student s)
	{
		this.s=s;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(s.k<12)
			s.saveMoney(s);

	}

}

测试程序:

package waytobuildthread;

import person.Student;

public class RunnableTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student tom=new Student();
		Student jack=new Student();
		tom.total=1000;
		tom.perMonth=200;
		tom.name="Tom";
		jack.total=1500;
		jack.perMonth=100;
		jack.name="Jack";
		
		ImplementRunnable t1=new ImplementRunnable(tom);
		new Thread(t1).start();
		
		ImplementRunnable t2=new ImplementRunnable(jack);
		new Thread(t2).start();
	}

}

运行程序,结果如下:

Jack第1月总共拥有1600元
Tom第1月总共拥有1200元
Tom第2月总共拥有1400元
Jack第2月总共拥有1700元
Tom第3月总共拥有1600元
Jack第3月总共拥有1800元
Jack第4月总共拥有1900元
Tom第4月总共拥有1800元
Tom第5月总共拥有2000元
Jack第5月总共拥有2000元
Tom第6月总共拥有2200元
Jack第6月总共拥有2100元
Jack第7月总共拥有2200元
Tom第7月总共拥有2400元
Tom第8月总共拥有2600元
Jack第8月总共拥有2300元
Tom第9月总共拥有2800元
Jack第9月总共拥有2400元
Jack第10月总共拥有2500元
Tom第10月总共拥有3000元
Tom第11月总共拥有3200元
Jack第11月总共拥有2600元
Tom存储结束,总共存储了:3200元
Jack存储结束,总共存储了:2600元

        由结果可以看出与继承Thread类效果基本相同,而且两者都是需要通过Thread对象的API来控制线程。

        Thread类和Runnable接口都是创建线程的方法,但是Runnable接口还是稍有优势,具体如下:

1.避免单继承的限制

2.适合多个相同程序代码的线程去处理同一个资源。

3.线程池只能放入实现Runnable接口和Callable接口的线程,不能直接放入继承Thread类的线程。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值