黑马软件工程师_09. api-线程、单例设计模式

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

九、黑马程序员_api-线程、单例设计模式

-------- android培训、java培训、期待与您交流 --------

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方法。

示例:
	//自定义一个类,实现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。
//定义示例:
class Demo1{
	public synchronized void method(){
			System.out.println("我是同步函数。");
		}
	}



当同步函数用static修饰时就是在synchronized前加上static关键字。静态的同步方法,使用的锁是该方法所在类的字节码文件对象, 类名.class。
<pre name="code" class="java">//定义示例:
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;
	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();
			this.name = name+"--"+count++;
			System.out.println(Thread.currentThread().getName()+"-----生产者---"+this.name);
			flag = true;
			condition_con.signal();
		}
		finally{
			//释放锁的动作一定要执行。
			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){
			//只为演示代码,简单处理。
				e.printstackTrace();
			}	
		}
	}
}

class Consumer implements Runnable{
	private Resource res;
	Consumer(Resource res){
		this.res = res;
	}
	public void run(){
		while(true){
			try{
				res.out();
			}
			catch (InterruptedException e){
				//只为演示代码,简单处理。
				e.printstackTrace();
			}
		}
	}
}
f.单例设计模式
模式就是在日常生活中人们实践过程中总结出来的,用来解决问题最行之有效的方法,它满足了人们复杂的业务需求。java中总的一共有23总设计模式。单例设计模式就是其中一种,解决了一个类在内存中只存在一个对像。
单例设计模式分为两种,都分为以下三步:
步骤:
a.将构造函数私有化;
b.在类中建立一个静态并私有的对像;
c.对外提供公共一个方法可以获取到该对像。
<pre name="code" class="java">//(1).饿汉式		
//示例:
class Single{
	//a.将构造函数私有化;
	private Single(){}
	//b.在类中建立一个静态并私有的对像;
	private static Single s = new Single();
	//c.对外提供公共一个方法可以获取到该对像。
	public static s getInstance(){
		return s;
	}
}
</pre><pre>
<pre name="code" class="java"><pre name="code" class="java">//(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;
	}
}