码迷,mamicode.com
首页 > 编程语言 > 详细

黑马程序员_09. api-线程及单例设计模式

时间:2015-05-18 09:08:18      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:线程   api   设计模式   解决方案   

黑马程序员_api-线程及单例设计模式
a.明确以下概念:
1.进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或叫一个控制单元。
2.线程:就是进程中的一个独立的控制单元。线程在控制着进程的执行,一个进程中至少有一个线程。
3.多线程:如果一个进程中存在着多个控制单元,那么这个进程是一个多线程的应用程序。JVM启动时是一个多线程。
b.创建线程的两种方式
1. java已经提供了对线程这类事物的描述。就是Thread类。并且这个类把要运行的代码存放在了run方法中。所以可以自定义一个类,让它继承Thread类,覆写这个类的run方法,就可以了。步骤:
(1).定义类继承Thread。
(2).复写Thread类中的run方法。目的是将自定义代码存储在run方法。让线程运行。
(3).调用线程的start方法.该方法两个作用:启动线程,调用run方法。

需要注意的是,run方法是一个一般方法,它只用来存线程要运行的代码,start方法才能让线程运行。

	示例:
			class Demo extends Thread{
				public void run(){
					for(int x=0; x<100; x++)
						System.out.println("demo run----"+x);
				}
			}
			class ThreadDemo {
				public static void main(String[] args) {
					//创建好一个线程。
					Demo d = new Demo();
					//开启线程并执行该线程的run方法
					d.start();。
					//主线程运行的代码。	
					for(int x=0; x<100; x++)
						System.out.println("Hello World!--"+x);
				}
			}
运行以上代码发现:自定义线程与主统一线程出现了随机运行的情况。这就是多线程的一个特性:随机性。谁抢到谁执行,至于执行多长,cpu说的算。发现自定义线程与主统一线程出现了随机运行的情况。这就是多线程的一个特性:随机性。谁抢到谁执行,至于执行多长,cpu说的算。要明确一点:在某一个时刻,只能有一个程序在运行(多核除外),cpu在做着快速的切换,看上去像是在同时运行一样。
2.通过观察发现Thread类的构造方法可以接收一个Runnable接口类型的对像,那么我们可以自定义一个类去实现这个接口,覆与这个接口的run方法,然后将这个对像作为实际参数传递给Thread类的构造函数即可。这样的操作避免了单继承的局限性。步骤:
(1).定义一个类实现Runnable接口,并覆写里面的run方法;
(2).创建Thread类的对像;
(3).将这个类的对像传递给Thread类的构函数;
(4).调用Thread对像的start方法。
<span style="white-space:pre">	</span>示例:
			//自定义一个类,实现Runnable接口,并覆写run方法。
			class Test implements Runnable{
				public void run(){
					for(int a=0; a<100; a++){
						System.out.println("Test--"+x);
					}
				}
			}
			class Thread_Runnable{
				public static void main(String[] args){
				//创建Thrread类的对像,将Test对像作传给Thread类的构造函数。
					Thread t = new Thread(new Test());
				//开启线程。
					t.start();
				}
			}

发现我们自定义类中的run方法被执行了!说明我们这样做也可以让线程帮我们运行我们自定义的代码。
c.关于线程的几个方法
(1).static Thread currentThread():获取当前线程对象;
(2).String getName(): 获取该线程名称;
(3).void setName(String name):设置该线程名称。
d.线程的5种状态:
(1).被创建;
(2).运行;
(3).临时状态(有执行资格但没有执行权);
(4).冻结(放弃了执行资格);
(5).消亡。
e.解决线程的安全问题
当一个线程对多条操作共享数据的代码执行的一部分。还没有执行完,另一个线程开始参与执行,这样容易出现安全隐患。在java中为解决这种安全隐患提供了专门的方案。如下介绍:
(1).同步函数
就是在函数的返回值前加上synchronized关键字,它持有的锁是this。
<span style="white-space:pre">	</span>定义示例:
			class Demo1{
				public synchronized void method(){
					System.out.println("我是同步函数。");
				}
			}
当同步函数用static修饰时
就是在synchronized前加上static关键字。静态的同步方法,使用的锁是该方法所在类的字节码文件对象, 类名.class。
<span style="white-space:pre">	</span>定义示例:
			class Demo2{
				public static synchronized void method(){
					System.out.println("我是用static修饰的同步函数。");
				}
			}
(2).同步代码块
就是对把需要同步的代码放在这个代码块当中,它使用的锁可以是任意对像。
格式:
synchronized(对像){
需要同步的代码;
}
(3).JDK1.5后对同步提供了显示的锁机制
它提供了多线程升级的解决方案,将同步Synchronized替换成现实Lock操作。将Object中的wait,notify notifyAll,替换了Condition对象。该对象可以Lock锁进行获取。在生产者、消费者的案例中实现了本方只唤醒对方的操作。
生产者、消费者示例代码:
class Resource
{
	private String name;
	private int count = 1;
	private boolean flag = false;	<span style="font-family: Arial, Helvetica, sans-serif;">	</span>
	private Lock lock = new ReentrantLock();
	private Condition condition_pro = lock.newCondition();
	private Condition condition_con = lock.newCondition();

	public  void set(String name)throws InterruptedException{
		lock.lock();
		try{
			while(flag)
				condition_pro.await();//t1,t2
			this.name = name+"--"+count++;

			System.out.println(Thread.currentThread().getName()+"-----生产者---"+this.name);
			flag = true;
			condition_con.signal();
		}
		finally{
<span style="white-space:pre">		</span><span style="font-family: Arial, Helvetica, sans-serif;">//释放锁的动作一定要执行。</span>
			lock.unlock();
		}
	}
 
	public  void out()throws InterruptedException{
		lock.lock();
		try{
			while(!flag)
				condition_con.await();
			System.out.println(Thread.currentThread().getName()+"----消费者----"+this.name);
			flag = false;
			condition_pro.signal();
		}
		finally{
			lock.unlock();
		}

	}
}

class Producer implements Runnable
{
	private Resource res;
	Producer(Resource res){
		this.res = res;
	}
	public void run(){
		while(true){
			try{
				res.set("+商品+");
			}
			catch (InterruptedException e){
<span style="white-space:pre">				</span><span style="font-family: Arial, Helvetica, sans-serif;">//只为演示代码,省略处理方式。</span>
<span style="white-space:pre">				</span>e.<span style="font-family: Arial, Helvetica, sans-serif;"><strong>printstackTrace();</strong></span><span style="white-space:pre">
</span>			}	
		}
	}
}

class Consumer implements Runnable{
	private Resource res<span style="font-family: Arial, Helvetica, sans-serif;">;</span>
	Consumer(Resource res){
		this.res = res;
	}
	public void run(){
		while(true){
			try{
				res.out();
			}
			catch (InterruptedException e){
<span style="white-space:pre">				</span><span style="font-family: Arial, Helvetica, sans-serif;">//只为演示代码,省略处理方式。</span>
<span style="font-family:Arial, Helvetica, sans-serif;"><span style="white-space:pre">								</span>e.</span><strong>printStackTrace</strong>
			}
		}
	}
}

f.单例设计模式
模式就是在日常生活中人们实践过程中总结出来的,用来解决问题最行之有效的方法,它满足了人们复杂的业务需求。java中总的一共有23总设计模式。单例设计模式就是其中一种,解决了一个类在内存中只存在一个对像。
单例设计模式分为两种,都分为以下三步:
步骤:
a.将构造函数私有化;
b.在类中建立一个静态并私有的对像;
c.对外提供公共一个方法可以获取到该对像。
<span style="white-space:pre">		</span>(1).饿汉式
			
			示例:
			class Single{
				private Single(){}
				private static Single s = new Single();
				public static s getInstance(){
					return s;
				}
			}
		(2).懒汉式
			懒汉式也称作类的延时加载,是方法被调用时对像才初始化。
			示例:
			class Single{
				private Single(){}
				private Single s = null;
				public void static s getInstance(){
					if(s==null){
						synchronized(Single.class){
							if(s==null){
								s = new Single();
							}
						}
					}
					return s;
				}
			}


黑马程序员_09. api-线程及单例设计模式

标签:线程   api   设计模式   解决方案   

原文地址:http://blog.csdn.net/lu_xiao_liang/article/details/45796855

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!