【java多线程与并发库】---传统java多线程<1>线程基本概念

一.线程的基本概念

 

1、入题:我们大家都知道,我们可以在一台计算机上同时聊天,看电影,下载视频等,完成上述任务的各个程序之间是完全相互独立的。但是他们在同一段时间内又同时处于运行状态。当然呢,它们在这一段时间内是分时使用计算机CPU时间的。只不过呢在CPU处理速度很快,划分的时间片段很短,所以给大家感觉上是多个程序在同时运行。

 

2、进程:

进程是程序的一次动态执行过程。这个过程包含了从程序代码从硬盘加载到内存、在内存中执行、执行结束等过程,实际上也就是进程的产生、发展、消亡的一个过程。

另外,每个进程都有自己的独立的地址空间和占用的系统资源,在进程执行结束后,进程会释放系统资源还给系统,供其他程序使用。

 

3、线程:

线程是比进程更小的一个执行单位,它是一段完成特定功能的代码

 

一个进程中可以包含多个线程。

 

与进程不同的是:同类线程将共享进程的地址空间和系统分配给进程的系统资源。线程本身并不占用资源,或者说只占用很少的一部分资源,通常只是寄存器中的数据及供程序使用的堆栈等。因此说在同一个进程的不同线程之间进行切换时,所花费的开销比在进程间切换小很多。所以,线程又被称为轻量级进程。

 

4java多线程:

 

一个进程中可以同时运行多个线程,每个线程执行不同的任务。

 

 

5、多线程的好处:

 

通过多线程程序设计,就可以将程序任务划分成几个并行执行的子任务,从而提高整个程序的执行效率和系统资源的利用率

 

 

 

 

二.线程的创建方式

线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。

每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。

当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:

  • 调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。
  • 非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常

Thread类的其中的两个构造方法

Thread()
          分配新的 Thread 对象。

Thread(Runnable target)
          分配新的 Thread 对象。

实例一:在Thread子类覆盖的run方法中编写运行代码:

public class ThreadTest01 {

	/**
	 * @param args
	 */

	public static void main(String[] args) {
		// TODO Auto-generated method stub
			Thread thread = new Thread(){
				@Override
				public void run(){ //覆写Thread类的run方法
					int i = 0;
					while(i<5){
						try {
							//使线程休眠1s,线程由运行状态进入阻塞状态,阻塞时间单位是毫秒
							//sleep()方法是静态的,不需要特定的Thread对象就可以调用它,注意会抛出异常
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						System.out.println("thread:"+Thread.currentThread().getName());//打印当前线程的名字
						System.out.println("2:"+this.getName());
						i++;
					}
				}
			};
			//调用start方法启动线程:用户不能直接调用Thread类中的run方法,而是需要调用start方法间接调用run方法。
			
			/*   Thread中run方法的definition
			 
			  public void run() {
					if (target != null) {
					    target.run();
					}
    			}
			  
			 */
			thread.start();


运行结果:

 

实例二:在传递给Thread类的Runnable对象的run方法中编写运行代码

public class ThreadTest01 {

	/**
	 * @param args
	 */

	public static void main(String[] args) {
		// TODO Auto-generated method stub
			Thread thread = new Thread(){
				@Override
				public void run(){ //覆写Thread类的run方法
					int i = 0;
					while(i<5){
						try {
							//使线程休眠1s,线程由运行状态进入阻塞状态,阻塞时间单位是毫秒
							//sleep()方法是静态的,不需要特定的Thread对象就可以调用它,注意会抛出异常
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						System.out.println("thread:"+Thread.currentThread().getName());//打印当前线程的名字
						System.out.println("2:"+this.getName());
						i++;
					}
				}
			};
			//调用start方法启动线程:用户不能直接调用Thread类中的run方法,而是需要调用start方法间接调用run方法。
			
			/*   Thread中run方法的definition
			 
			  public void run() {
					if (target != null) {
					    target.run();
					}
    			}
			  
			 */
			thread.start();
			
			
			Thread thread2 = new Thread(new Runnable(){
				@Override
				public void run(){ //覆写Thread类的run方法
					int i = 0;
					while(i<5){
						try {
							//使线程休眠1s,线程由运行状态进入阻塞状态,阻塞时间单位是毫秒
							//sleep()方法是静态的,不需要特定的Thread对象就可以调用它,注意会抛出异常
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						System.out.println("thread2:"+Thread.currentThread().getName());//打印当前线程的名字
						
						i++;
					}
				}
			});
			thread2.start();
			
	}

}


运行结果:

那么大家可以思考这样两个问题:

问题一、如果Thread类的run方法被覆写了,并且为Thread类传递的Runnable对象的run方法也编写了运行代码?那么程序会执行哪一个run方法呢?

实例三:来说明上述问题

 

public class ThreadTest01 {

	/**
	 * @param args
	 */

	public static void main(String[] args) {
		
		new Thread(
				new Runnable(){
					public void run(){ //覆写Thread类的run方法
						int i = 0;
						while(i<5){
							try {
								//使线程休眠1s,线程由运行状态进入阻塞状态,阻塞时间单位是毫秒
								//sleep()方法是静态的,不需要特定的Thread对象就可以调用它,注意会抛出异常
								Thread.sleep(1000);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							System.out.println("Runnable:"+Thread.currentThread().getName());//打印当前线程的名字
							
							i++;
						}
					}
				}		
			){
				public void run(){ //覆写Thread类的run方法
					int i = 0;
					while(i<5){
						try {
							//使线程休眠1s,线程由运行状态进入阻塞状态,阻塞时间单位是毫秒
							//sleep()方法是静态的,不需要特定的Thread对象就可以调用它,注意会抛出异常
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						System.out.println("thread:"+Thread.currentThread().getName());//打印当前线程的名字
						
						i++;
					}
				}
			}.start();
			
	}

}


运行结果为:

 

 

总结:在Thread子类的run方法和传递给Thread的Runnable对象的run方法都被覆写的时候,程序执行Thread子类的run方法。

 

 

问题二:如果Thread类的run方法没有被覆写,并且为Thread类传递的Runnable对象的run方法也编写了运行代码?那么程序会执行哪一个run方法呢?

 

总结:显然是调用Runnable对象的run方法:实例二已经证明

 

 

下一篇将讲述Thread的两种创建方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值