2016/10/10 github的简单实用 java 单例设计模式

今天学习一下如何使用github,以及java 设计模式 一天了解一种设计模式,
先https://github.com/git-for-windows/git/releases
下载了Git-2.10.1-64-bit.exe
安装一路next,如果想详细了解安装请看http://blog.csdn.net/vipzjyno1/article/details/22098621
这个是命令行版本的,先记住一些基本的命令
GitHub操作流程 :

第一次提交 :
方案一 : 本地创建项目根目录, 然后与远程GitHub关联, 之后的操作一样;
– 初始化Git仓库 :git init ;
– 提交改变到缓存 :git commit -m ‘description’ ;
– 本地git仓库关联GitHub仓库 : git remote add origin [email protected]:han1202012/TabHost_Test.git ;
– 提交到GitHub中 : git push -u origin master ;
方案二 : 方案二就是不用关联GitHub仓库, 直接从GitHub冲克隆源码到本地, 项目根目录也不用创建;
– 从GitHub上克隆项目到本地 :git clone [email protected]:han1202012/NDKHelloworld.git , 注意克隆的时候直接在仓库根目录即可, 不用再创建项目根目录 ;
– 添加文件 :git add ./* , 将目录中所有文件添加;
– 提交缓存 :git commit -m ‘提交’;
– 提交到远程GitHub仓库 : git push -u origin master ;
之后修改提交 :
– 与GitHub远程仓库同步 :git pull ;
– 查看文件变更 : git status ;
– 提交代码到本地缓存 : git commit -m ‘description’;
–提交代码到远程GitHub仓库 :git push ;

.gitignore用法 : 开放模式 注明忽略的文件 直接列出文件名, 保守模式 注明保留的文件 !文件名 ;

Git标签操作 : 轻量级标签, 带注释标签;
–查看标签 :git tag ;
–添加标签 : 轻量级标签git tag tagName , 带注释标签git tag -a tagName -m ‘description’ ;
–删除标签 :git tag -d tagName ;
–提交标签到GitHub中 : git push origin –tags ;

Git分支操作: 创建分支后, 分支操作不会影响master分支, 但是master分支改变会影其它分支;
–列出分支 :git branch ;
–切换分支 :git checkout master ;
–提交分支 : git push origin branchName ;
–删除分支 : git branch -d branchName , 强制删除分支 git branch -D branchName ;
–合并分支 : git merge branchName ;
安装完成之后http://www.cnblogs.com/ustcseven/p/5716112.html

根据这个我成功的失败了,怎么着也提交不上去,
还是直接图形化界面吧,
http://www.cr173.com/soft/82437.html
图形化界面就简单多了,成功的上传了,
https://github.com/freegg/simple/

设计模式,从常用的单例模式开始
http://devbean.blog.51cto.com/448512/203501/
简单实现

饿汉式
public class SingletonClass{
    private static final SingletonClass instance = new SingletonClass();
    private SingleClass(){}
    public static SingletonClass getInstance(){
        return instance;
    }
}

在类初始化时,已经实例化,天生线程安全,但是无论类是否被使用,都会实例化,性能问题,

懒汉式
public class SingletonClass{
private static SingletonClass instance = null;
private SingleClass(){};
public static SingletonClass getInstance(){
    if(instance == null){
        instance = new SingletonClass();
    }
    return instance;
}

}

根据是否为空来判断是否实例化,在多线程时,容易出现问题,不唯一了,因此加锁

public class SingletonClass{
    private static SingletonClass instance = null;
    private SingletonClass(){};
    public synchronized static SingletonClass getInstance(){
        if(instance==null){
            instance = new SingletonClass();
        }
        return instance;
    }
}

加锁之后,一个线程必须等待另一个线程执行完之后才使用,保证单例,同时性能问题,被synchronized修饰的代码块比正常的代码块慢很多,

public class SingletonClass { 

  private static SingletonClass instance = null; 

  public static SingletonClass getInstance() { 
    synchronized (SingletonClass.class) { 
      if(instance == null) { 
        instance = new SingletonClass(); 
      } 
    }     
    return instance; 
  } 

  private SingletonClass() { 

  } 

}

把锁的位置调整加在if语句中,但是调用getInstance方法还可能同步,双重检查

public class SingletonClass { 

  private static SingletonClass instance = null; 

  public static SingletonClass getInstance() { 
    if (instance == null) { 
      synchronized (SingletonClass.class) { 
        if (instance == null) { 
          instance = new SingletonClass(); 
        } 
      } 
    } 
    return instance; 
  } 

  private SingletonClass() { 

  } 

编译器优化,在不改变原来语义的情况下,通过调整语句顺序,来让程序运行的更快。这个过程成为reorder。要知道,JVM只是一个标准,并不是实现。JVM中并没有规定有关编译器优化的内容,也就是说,JVM实现可以自由的进行编译器优化。

下面来想一下,创建一个变量需要哪些步骤呢?一个是申请一块内存,调用构造方法进行初始化操作,另一个是分配一个指针指向这块内存。这两个操作谁在前谁在后呢?JVM规范并没有规定。那么就存在这么一种情况,JVM是先开辟出一块内存,然后把指针指向这块内存,最后调用构造方法进行初始化。

下面我们来考虑这么一种情况:线程A开始创建SingletonClass的实例,此时线程B调用了getInstance()方法,首先判断instance是否为null。按照我们上面所说的内存模型,A已经把instance指向了那块内存,只是还没有调用构造方法,因此B检测到instance不为null,于是直接把instance返回了——问题出现了,尽管instance不为null,但它并没有构造完成,就像一套房子已经给了你钥匙,但你并不能住进去,因为里面还没有收拾。此时,如果B在A将instance构造完成之前就是用了这个实例,程序就会出现错误了!

在JDK 5之后,Java使用了新的内存模型。volatile关键字有了明确的语义——在JDK1.5之前,volatile是个关键字,但是并没有明确的规定其用途——被volatile修饰的写变量不能和之前的读写代码调整,读变量不能和之后的读写代码调整!因此,只要我们简单的把instance加上volatile关键字就可以了。

public class SingletonClass { 

  private volatile static SingletonClass instance = null; 

  public static SingletonClass getInstance() { 
    if (instance == null) { 
      synchronized (SingletonClass.class) { 
        if(instance == null) { 
          instance = new SingletonClass(); 
        } 
      } 
    } 
    return instance; 
  } 

  private SingletonClass() { 

  } 

}

然而,这只是JDK1.5之后的Java的解决方案,那之前版本呢?其实,还有另外的一种解决方案,并不会受到Java版本的影响:

public class SingletonClass { 

  private static class SingletonClassInstance { 
    private static final SingletonClass instance = new SingletonClass(); 
  } 

  public static SingletonClass getInstance() { 
    return SingletonClassInstance.instance; 
  } 

  private SingletonClass() { 

  } 

}

在这一版本的单例模式实现代码中,我们使用了Java的静态内部类。这一技术是被JVM明确说明了的,因此不存在任何二义性。在这段代码中,因为SingletonClass没有static的属性,因此并不会被初始化。直到调用getInstance()的时候,会首先加载SingletonClassInstance类,这个类有一个static的SingletonClass实例,因此需要调用SingletonClass的构造方法,然后getInstance()将把这个内部类的instance返回给使用者。由于这个instance是static的,因此并不会构造多次。

由于SingletonClassInstance是私有静态内部类,所以不会被其他类知道,同样,static语义也要求不会有多个实例存在。并且,JSL规范定义,类的构造必须是原子性的,非并发的,因此不需要加同步块。同样,由于这个构造是并发的,所以getInstance()也并不需要加同步。

你可能感兴趣的:(单例模式-githu)