黑马程序员—多线程

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

了解多线程

了解多线程,先了解概念:

什么是进程。

        进程:正在执行的应用程序。

那么什么是线程呢?

        线程:应用程序的执行单元,执行路径。

什么是单线程?

        单线程:顾名思义,一个应用程序在执行的过程中只有一条执行路径。

那么什么是多线程?

        多线程:指的是一个应用程序有多条执行路径。

举例:

在生活中,很形象的例子譬如说是学校食堂。有多个窗口,意味着更多的吞吐量和更高的效率,若是只有一个窗口,后果可能是一面是饭菜没有如期卖完

会造成浪费,一面是部分师生还饿着肚子。而开辟多个窗口本质就是线程的一种体现。

多线程的意义: 

        多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。

        线程是在同一时间需要完成多项任务的时候实现的。

多线程的实现

	实现多线程有两种方法
	一是继承thread类:
思路	A:自定义类继承Thread类。
  		B:在自定义类中重写run方法。
 		C:创建自定义类对象。
		D:启动线程。
//使用Thread实现线程
class MyThread extends Thread
{
	private String name;
	public MyThread(String name ){
		this.name=name;
	}
	public void run(){
		for(int i=0;i<10;i++){
			System.out.println("线程"+name+i);
		}	
	}
}
public class ThreadDemo01
{
	public static void main(String args[]){
		MyThread A = new MyThread("A");   //实例线程对象
		MyThread B = new MyThread("B");   //实例线程对象
		A.start();
		B.start();
	}
}
二是通过实现runnable接口。
为什么会有这第二种方法呢?因为如果一个类本身就有父类了,我还想实现多线程,通过继承Thread类就实现不了。 所有就有实现Runnable接口的方式。
思路	A:自定义类实现Runnable接口。
  		B:重写run()方法。
  		C:创建自定义类对象。
  		D:创建线程对象,把自定义类对象的作为构造参数传递。
  		E:启动线程对象。
//使用Runnable实现线程
class MyThread implements Runnable
{
	private String name;
	public MyThread(String name){
		this.name=name;
	}
	public void run(){
		for(int i=1;i<=10;i++){
			System.out.println("线程"+name+i);
		}
	}
}
public class RunnableDemo01
{
	public static void main(String args[]){
		MyThread A = new MyThread("A");  //实例化线程要执行的任务
		MyThread B = new MyThread("B");  //实例化线程要执行的任务
		Thread Ta = new Thread(A);    //实例化线程,并传递其要执行的任务
		Thread Tb = new Thread(B);    //实例化线程,并传递其要执行的任务
		Ta.start();    //启动线程
		Tb.start();
	}
}
补充思路:通过runnable实现多线程,实现Runnable接口的类必须使用Thread类的实例才能创建线程。通过Runnable接口创建线程分为两步:
	1. 将实现Runnable接口的类实例化。
	2. 建立一个Thread对象,并将第一步实例化后的对象作为参数传入Thread类的构造方法。
	3. 最后通过Thread类的start方法建立线程。
注意:线程的随机性和延迟性,这些将会引发一些安全问题。
	如何判断是否有一些安全问题呢?
				1  	是否有共享数据。
				2	共享语句是否被多条语句操作。
				3	是否有多个线程在执行。
既然有安全问题,那么如何解决呢?
		第一种方法
				1	同步代码块
					synchronized(锁对象){
					被同步的代码
					}
 
		第二种方法
				2	同步方法
					在方法上加同步关键字
					锁对象是this。
				注意:静态同步方法的锁对象是当前类名.class。(当前的字节码文件对象)
用多线程模拟买票的案例
public class Tickets implements Runnable
		{
			private int tickets = 100;
			private Object obj = new Object();
			@Override
			public void run()
			{
				while(true)
				{
					synchronized(obj)
					{
						if(tickets>0)
						{
							System.out.println(Thread.currentThread().getName()+"正在售出"+(tickets--)+"张票");
						}
					}
				}
			}
		}		
		public class Test
		{
			public static void main(String[] args)
			{
				Tickets t = new Tickets();

				Thread t1 = new Thread(t,"窗口1");
				Thread t2 = new Thread(t,"窗口2");
				Thread t3 = new Thread(t,"窗口3");
				Thread t4 = new Thread(t,"窗口4");
			
				t1.start();
				t2.start();
				t3.start();
				t4.start();
			}
		}
start()和run()方法的区别:
run()仅仅是封装了被线程执行的代码。
  start()可以启动线程,并让jvm自动调用run()方法
线程的生命周期:新建-就绪-(阻塞)-运行--死亡,五个阶段。
	当用new 创建完一个线程对象后,该线程处于新建状态
    	当线程对象调用了start()后,该线程处于就绪状态
    	如果处于就绪状态的线程获得CPU时间片,开始执行run方法的线程执行体,该线程处于运行状态
   	如果线程调用了sleep()或者调用了一个阻塞式IO方法等,该线程处于阻塞状态
   	如果线程的run()执行完成或者抛出一个未捕获的异常等原因,该线程处于死亡状态
---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值