天天看点

Thread,单例模式

创建线程:

package thread;

public class MutiThreadDemo {

	public static void main(String[] args) {
		SonOfThread s1= new SonOfThread("zhangsan");
		SonOfThread s2= new SonOfThread("lisi");
		Thread t1 = new Thread(new RunnableImpl());
		Thread t2 = new Thread(new RunnableImpl());
		/*
		 * 不论哪种方法都是通过start来启动线程的,启动线程后,JVM会自动调用run方法
		 * 直接.run()不是启动线程,而是调用run方法。
		 */
		s1.start();
		s2.start();
		t1.start();
		t2.start();
		for(int j=0;j<10;j++){
			for(int i=0;i<1000000;i++){}
			System.out.println(Thread.currentThread().getName()+"....."+j);
		}
	}
}
class SonOfThread extends Thread{
	/*
	 * 自定义线程类继承Thread,重写run方法,使用的是Thread类的空参构造方法
	 */
	private String name;
	public SonOfThread(String name) {
		super();
		this.name = name;
	}
	@Override
	public void run() {
		for(int j=0;j<10;j++){
			for(int i=0;i<1000000;i++){}
			System.out.println(Thread.currentThread().getName()+"....."+j);
		}
	}
}
class RunnableImpl implements Runnable{
	/*
	 * 定义一个类实现Runnable接口,重写run方法,使用的是Thread类的Thread(Runnable target)
	 * 构造方法,推荐使用实现接口的创建方式
	 * 好处是:1、 可将线程任务封装成对象2、避免java单继承的局限性
	 */
	public void run() {
		for(int j=0;j<10;j++){
			for(int i=0;i<1000000;i++){}
			System.out.println(Thread.currentThread().getName()+"....."+j);
		}
	}
}
           

线程安全的单例模式:

package thread;
/*
 * 线程安全的懒汉式单例模式,既然为单例就要保证构造方法私有化,提供一
 * 个公共的方法可以获取到单例。static说明:既然是懒汉单例模式,那么在
 * 该单例还未实例化之前,该类是没有对象的,所以获取对象的getInstance
 * 方法不能通过具体的对象来调用,那么就只能定义为static,通过类来调用,
 * 而单例的实例化是在getInstance方法中完成的,所以s也应该定义为static。
 * 实例化之前加一个判断是为了保证单例,外层加同步锁是了解决线程安全为题,
 * 防止出现多个实例,而锁的外层再加一个判断是为了解决效率问题,这样线程
 * 执行的时候就不必每次都判断锁,另外一个:即使是有了外层的判断,内层的
 * 也不可以省略,因为有可能一个线程执行到第一个判断条件是判断s=null为真,
 * 还未拿到锁就失去了cpu的执行权而停止。这时第二个线程也判断s=null为真,
 * 那么无论这两个线程谁先拿到锁,如果没有内层的判断,最终都会实例化出两个
 * 对象。
 */
public class Singleton {

	private static Singleton s = null;
	private Singleton(){}
	public static Singleton getInstance(){
		if(s==null){
			synchronized(Singleton.class){
				if(s==null){
					s = new Singleton();
				}
			}
		}
		return s;
		
	}
}
           

继续阅读