java实现多线程的两个方法

方法一:

实现多线程只需继承Thread类,然后重写run方法

然后在main方法中创建一个Thread子类对象,调用start方法,启动线程

注意我们不可以直接调用run方法,如果直接调用run无法实现多线程,调用start方法后,会将该线程添加到线程组中,交给CPU进行处理调度,系统会自动调用run方法


举个例子,龟兔赛跑,分别有两个类代表乌龟和兔子,都继承了Thread类,并且重写了run方法


public class Rabbit extends Thread {

	@Override
	public void run() {
		for(int i=0;i<10;i++){
			System.out.println("rabbit running!"+i);
		}
	}
}

class Tortoise extends Thread{

	@Override
	public void run() {
		for(int i=0;i<10;i++){
			System.out.println("tortoise running!"+i);
		}
	}
	
}


在main方法中创建两个对象,测试多线程


public class RabbitTest {
	public static void main(String[] args) {
		Rabbit rabbit=new Rabbit();
		Tortoise tortoise=new Tortoise();

		rabbit.start();
		tortoise.start();
	}
}



每次运行都不相同,因为处理及对于线程的调度不尽相同,这里包含了main,兔子,乌龟,三个线程,抛开gc,和异常异常处理,兔子和乌龟谁先抢占到CPU,谁就先运行


rabbit running!0
tortoise running!0
rabbit running!1
tortoise running!1
rabbit running!2
tortoise running!2
rabbit running!3
tortoise running!3
rabbit running!4
tortoise running!4
rabbit running!5
rabbit running!6
rabbit running!7
rabbit running!8
rabbit running!9
tortoise running!5
tortoise running!6
tortoise running!7
tortoise running!8
tortoise running!9









方法二:

由于java是单继承,而使用方法一时,子类不能再继承其他父类,这对于有些必须继承其他父类的类是无法实现多线

程的,所以就有了方法二,通过实现Runnable接口+静态代码实现多线程


在知道如何实现多线程之前,需要了解一下什么是静态代理设计模式

静态代理有两个类,一个是真实的角色,一个是代理角色,其中代理角色需持有真实角色的引用

并且二者需要实现相同的接口


举个例子,比如你要结婚找婚礼策划公司策划婚礼,那么此时你就是真实角色,婚礼策划公司就是代理角色


public class StaticProxy {
	public static void main(String[] args) {
		//创建真实角色
		You you =new You();
		
		//创建代理角色+真实角色的引用
		WeddingCompany wc=new WeddingCompany(you);
		
		//结婚
		wc.marry();
	}
}


interface Marry{
	void marry();
}


class You implements Marry{

	@Override
	public void marry() {
		
		System.out.println("you married johnny depp!");
	}
	
}


class WeddingCompany implements Marry{

	private Marry you;
	
	public WeddingCompany() {
		// TODO Auto-generated constructor stub
	}
	
	
	public WeddingCompany(Marry you) {
		this.you = you;
	}

	private void before(){
		System.out.println("get ready for wedding!");
	}
	
	private void after(){
		System.out.println("get ready for party!");
	}

	@Override
	public void marry() {
		before();
		you.marry();
		after();
	}	
}


输出结果为 

get ready for wedding!
you married johnny depp!
get ready for party!



那么这里的You就是你设计的类,weddingCompant就是Thread类,而Marry就是Runnable接口

Thread类已经实现了Runnable接口,所以你设计的类只要实现Runnable接口即可


public class Programer implements Runnable {

	@Override
	public void run() {
		for(int i=0;i<10;i++){
			System.out.println("watching..."+i);
		}
		
	}
}

public class ProgramerTest {
	public static void main(String[] args) {
		Programer p=new Programer();
		Thread thread=new Thread(p);
		thread.start();
		
		for(int i=0;i<10;i++){
			System.out.println("eating..."+i);
		}
	}
}





使用Runnable+静态代理的好处:

1.避免单继承的局限性

2.便于共享资源



使用方法二模拟买票机制(两个买票窗口)


public class web12306 implements Runnable{

	public int num=50;
	
	@Override
	public void run() {
		while(true){
			if(num<=0){
				break;
			}
			
			System.out.println(Thread.currentThread().getName()+"抢到了 "+num--);
		}
	}
	
	public static void main(String[] args) {
		//真实角色
		web12306 web=new web12306();
		
		//两个代理
		Thread t1=new Thread(web);
		Thread t2=new Thread(web);
		
		//启动线程
		t1.start();
		t2.start();
		
	}
}



Thread-1抢到了 10
Thread-0抢到了 9
Thread-1抢到了 8
Thread-0抢到了 7
Thread-1抢到了 6
Thread-1抢到了 4
Thread-1抢到了 3
Thread-1抢到了 2
Thread-0抢到了 5
Thread-1抢到了 1






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值