Java多线程(一)Thread类与Runnable接口

1、线程

a 进程、线程都是实现并发机制的有效手段;

b 线程是比进程更小的执行单位,是在进程基础上的进一步划分;

c 一个程序运行,可能多个线程同时运行

例如,打开word是启动了一个系统进程,里面的拼写检查就是一个小的线程。

2、Thread类

Thread类属于java.lang.Object。在文档中的定义:public class Thread extends Object implements Runnable

可以看出,Thread类也实现了Runnable接口,一个类要继承thread类必须重写run()方法。

实例:

定义一个线程类MyThread实现Thread

public class MyThread extends Thread{
	private String name;//再类中定义一个属性
	public MyThread(String name){
		this.name = name;
	}
//	一定要重写Thread类中的run()方法,此方法为线程的主体
	public void run(){
		for(int i=0; i<10; i++){
			System.out.println(name+"运行, i="+i);
		}
	}
}
实例化并运行下run()方法:

public class ThreadDemo01 {
	public static void main(String[] args) {
		MyThread mt1 = new MyThread("线程A");
		MyThread mt2 = new MyThread("线程B");
		mt1.run();
		mt2.run();
	}
}

运行结果:

线程A运行, i=0
线程A运行, i=1
线程A运行, i=2
线程A运行, i=3
线程A运行, i=4
线程A运行, i=5
线程A运行, i=6
线程A运行, i=7
线程A运行, i=8
线程A运行, i=9
线程B运行, i=0
线程B运行, i=1
线程B运行, i=2
线程B运行, i=3
线程B运行, i=4
线程B运行, i=5
线程B运行, i=6
线程B运行, i=7
线程B运行, i=8
线程B运行, i=9

可以看出先执行了mt1后执行mt2,并没有交错同时运行,所以以上方法并没有启动多线程。

要想使用多线程,必须调用从Thread类中继承来的start()方法。

public class ThreadDemo02 {
	public static void main(String[] args) {
		MyThread mt1 = new MyThread("线程A");
		MyThread mt2 = new MyThread("线程B");
		mt1.start();
		mt2.start();
	}
}
运行结果:(可能的一种)

线程B运行, i=0
线程A运行, i=0
线程B运行, i=1
线程A运行, i=1
线程B运行, i=2
线程A运行, i=2
线程B运行, i=3
线程A运行, i=3
线程B运行, i=4
线程A运行, i=4
线程B运行, i=5
线程B运行, i=6
线程A运行, i=5
线程B运行, i=7
线程A运行, i=6
线程A运行, i=7
线程A运行, i=8
线程A运行, i=9
线程B运行, i=8
线程B运行, i=9

以上实现了多线程,两个线程交错运行,哪个线程对象抢到了CPU资源,哪个线程就可以运行。

注:如果一个类通过继承Thread类来实现,那么只能调用一次start()方法,若调用多次就会抛出异常

mt1.start();

mt2.start();

异常:java.lang.IllegalThreadStateException

3、Runnable接口

下面通过实例看实现Runnable接口如何启动多线程

还是那个线程类我们让他实现Runnable接口

public class MyThread2 implements Runnable{
	private String name;
	public MyThread2(String name){
		this.name = name;
	}
//	重写Runnable接口中的run()方法
	public void run(){
		for(int i=0; i<10; i++){
			System.out.println(name+"运行, i="+i);
		}
	}
}
实例化启动线程:

public class ThreadDemo04 {
	public static void main(String[] args) {
		MyThread2 mt1 = new MyThread2("线程A");
		MyThread2 mt2 = new MyThread2("线程B");
		Thread t1 = new Thread(mt1);
		Thread t2 = new Thread(mt2);
		t1.start();
		t2.start();
	}
}

运行结果:

线程A运行, i=0
线程B运行, i=0
线程A运行, i=1
线程B运行, i=1
线程A运行, i=2
线程B运行, i=2
线程A运行, i=3
线程A运行, i=4
线程A运行, i=5
线程A运行, i=6
线程A运行, i=7
线程A运行, i=8
线程A运行, i=9
线程B运行, i=3
线程B运行, i=4
线程B运行, i=5
线程B运行, i=6
线程B运行, i=7
线程B运行, i=8
线程B运行, i=9
要想启动一个多线程,必须调用start()方法,如果继承thread类就可以直接使用其start()方法;Runnable接口没有start()方法的定义,还是要依靠thread类。

实例化Runnable子类对象--->用Runnable实例去实例化Thread类对象----->启动线程通过thread实例对象

4、Thread类与Runnable接口

Thread类:通过子类继承,有单继承局限;不能一个实例重复调用start()方法,不能实现资源共享。

Runnable:避免单继承局限;可被多个线程共享;

下面通过一个卖票的实例来对比资源共享的问题

定义一个线程类继承Thread类:

public class MyThread3 extends Thread{
	private int ticket = 5;//一共5张票
	public void run(){
		for(int i=0; i<100; i++){//超出票数的循环,卖完即止
			if(ticket > 0){
				System.out.println("卖票:ticket="+ticket--);
			}
		}
	}
}
实例化启动线程:

public class ThreadDemo05 {
	public static void main(String[] args) {
		MyThread3 my1 = new MyThread3();
		MyThread3 my2 = new MyThread3();
		MyThread3 my3 = new MyThread3();
		my1.start();
		my2.start();
		my3.start();
	}
}

运行结果:

卖票:ticket=5
卖票:ticket=5
卖票:ticket=5
卖票:ticket=4
卖票:ticket=3
卖票:ticket=4
卖票:ticket=2
卖票:ticket=1
卖票:ticket=3
卖票:ticket=4
卖票:ticket=2
卖票:ticket=1
卖票:ticket=3
卖票:ticket=2
卖票:ticket=1
以上启动了三个线程,但是每个线程却卖了各自的5张票,没有实现资源共享。

实现Runnable接口,来线程资源共享

定义一个线程类实现Runnable接口:

public class MyThread4 implements Runnable{
	private int ticket = 5;
	@Override
	public void run() {
		for(int i=0; i<100; i++){
			if(ticket > 0){
				System.out.println("卖票:ticket="+ticket--);//第一次循环ticket--为5,ticket变为4
			}
		}		
	}
}
实例化调用Thread的start()启动线程:

public class ThreadDemo06 {
	public static void main(String[] args) {
		MyThread4 my = new MyThread4();
		new Thread(my).start();
		new Thread(my).start();
		new Thread(my).start();
	}
}

运行结果:

卖票:ticket=5
卖票:ticket=3
卖票:ticket=4
卖票:ticket=1
卖票:ticket=2

启动了三个线程,一共随机卖出这5张票,实现了资源贡献

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值