java 多线程

在Java中,创建线程有两种方式,其中一种是继承Thread ,另外一种是实现Runnable接口。

这两种方法各有优点,继承的那种方便一点,但是在已继承其他类的情况下是有点儿麻烦的,这时要使用内部类来实现。但是在实现Runnable接口的却不存在这种情况,接口可以同时衔接多个接口。在实现Runnable接口是,可以创建多个线程对同一个数据库进行操作,比如售票系统,这个在内部类继承Thread也是可以实现的。

 

 

进程与线程是两个不同的概念。一个进程中可以有多个进程。比如说我们执行执行一个程序,这是一个进程,在这个程序中可能异已经启动多个线程了。

/**
 * 简单测试线程
 * 继承thread来创建线程
 * @author gaosi
 *
 */
public class Test extends Thread{
	String name;
	public Test(String name){
		this.name=name;
	}
	public void run(){
		for(int i=0;i<5;i++)
		{
			System.out.println(name+"执行"+i+"次");
		}
	}
	public static void main(String[] args) {
		Test ta=new Test("A");
		Test tb=new Test("B");
		ta.run();
		tb.run();
	}
}

 

输出结果:

A执行0次
A执行1次
A执行2次
A执行3次
A执行4次
B执行0次
B执行1次
B执行2次
B执行3次
B执行4次

这是单线程即main线程执行的结果,(这是我们并没有启动多线程,线程启动用star())。

我们启动一下多线程来试一下刚才的输出是否会一样?

	public static void main(String[] args) {
		Test ta=new Test("A");
		Test tb=new Test("B");
		ta.start();
		tb.start();
	}
}

 

输出结果:

A执行0次
B执行0次
A执行1次
B执行1次
A执行2次
B执行2次
A执行3次
B执行3次
A执行4次
B执行4次

也有可能是

B执行0次
A执行0次
A执行1次
A执行2次
B执行1次
A执行3次
B执行2次
A执行4次
B执行3次
B执行4次

等。总之输出结果不唯一。

我的个人理解是:可能是系统的问题,系统给予每个线程的时间是随机的轮换,也即是说这得看系统心情看哪个线程顺眼一点……

上面提到继承Thread不可以实现资源共享,(在内部类继承Thread是可以的),实现Runnable接口到时轻松实现资源共分享,如售票系统。

下面用简单的代码演示一下:

public class Test extends Thread{
	int ticket =10;
	String name;
	public Test(String name){
		this.name=name;
	}
	public void run(){
		for(int i=0;i<5;i++)
		{
			System.out.println(name+"剩余的票数"+ticket);
			ticket--;
		}
	}
	public static void main(String[] args) {
		Test ta=new Test("A");
		Test tb=new Test("B");
		ta.start();
		tb.start();
	}
}

 

输出结果:

A剩余的票数10
B剩余的票数10
B剩余的票数9
B剩余的票数8
B剩余的票数7
B剩余的票数6
A剩余的票数9
A剩余的票数8
A剩余的票数7
 A剩余的票数6

输出结果不唯一,但是输出剩余的票数是唯一的。原因上面所讲。

对比一下实现Runnable接口的:

 

class Test implements Runnable{
	int ticket=10;//定义票数为10
	public Test(){}
	public void run(){
		for(;ticket>0;){
			System.out.println(Thread.currentThread().getName()+"在售票!剩余票数"+ticket--);
			
			
		}
	}
	public static void main(String[] args) {
		Test t1=new Test();
		/**
		 * 启动多个线程,对同一个数据库进行操作
		 */
		new Thread(t1,"A").start();
		new Thread(t1,"B").start();
		new Thread(t1,"C").start();
	}
}

 

 输出结果:

B在售票!剩余票数8
B在售票!剩余票数7
C在售票!剩余票数9
A在售票!剩余票数10
C在售票!剩余票数5
B在售票!剩余票数6
C在售票!剩余票数3
A在售票!剩余票数4
C在售票!剩余票数1
B在售票!剩余票数2

或者:

A在售票!剩余票数10
A在售票!剩余票数8
A在售票!剩余票数7
A在售票!剩余票数5
A在售票!剩余票数4
A在售票!剩余票数3
A在售票!剩余票数2
A在售票!剩余票数1
B在售票!剩余票数9
C在售票!剩余票数6

//看数据。输出结果不唯一

如果票数不是定义为全局变量,结果会不同的

/

辨别一下两种写法的区别

/**
 * 继承thread,用内部类来实现数据共享
 */
public class Test extends Thread{
	int ticket=10;//定义票数,全局
	public void run(){
		for(;ticket!=0;){
			System.out.println(Thread.currentThread().getName()+"正在售票"+ticket--);
		}
	}
	
	
	public static void main(String[] args) {
		Test t=new Test();
		/**
		 * 创建线程,并且启动多线程
		 */
		new Thread(t,"A").start();
		new Thread(t,"B").start();
		new Thread(t,"c").start();
		
	}
}

 

其中一种输出结果:

A正在售票10
A正在售票7
A正在售票6
A正在售票5
A正在售票4
A正在售票3
A正在售票2
A正在售票1
B正在售票8
c正在售票9

public class Test extends Thread{
	int ticket=10;//定义票数,全局
	public void run(){
		for(;ticket!=0;){
			System.out.println(Thread.currentThread().getName()+"正在售票"+ticket--);
		}
	}
	
	
	public static void main(String[] args) {
		/**
		 * 创建线程,并且启动多线程
		 */
		Test t1=new Test();
		Test t2=new Test();
		Test t3=new Test();
		t1.start();
		t2.start();
		t3.start();
		/*new Thread(t,"A").start();
		new Thread(t,"B").start();
		new Thread(t,"c").start();*/
		
	}
}

 

其中一种结果为:

Thread-0正在售票10
Thread-0正在售票9
Thread-0正在售票8
Thread-0正在售票7
Thread-1正在售票10
Thread-1正在售票9
Thread-1正在售票8
Thread-1正在售票7
Thread-1正在售票6
Thread-0正在售票6
Thread-1正在售票5
Thread-1正在售票4
Thread-1正在售票3
Thread-1正在售票2
Thread-1正在售票1
Thread-2正在售票10
Thread-2正在售票9
Thread-2正在售票8
Thread-2正在售票7
Thread-0正在售票5
Thread-0正在售票4
Thread-0正在售票3
Thread-0正在售票2
Thread-0正在售票1
Thread-2正在售票6
Thread-2正在售票5
Thread-2正在售票4
Thread-2正在售票3
Thread-2正在售票2
Thread-2正在售票1
《完》

个人觉得实现Runnable接口更好一点……

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值