月度归档:2015年05月

像编程一样写文章—Markdown

Markdown是什么

  • 是一种极其简单的标记语言,写的时候只需要普通编辑器即可;
  • 它可以使文本内存具有某种格式;
  • Markdown设计理念使文本易读、易写
  • 文件后缀名:.md 、 .markdown、 .mdown

  Markdown可以让你像编程一样写文章,没错就是这么神奇!不要听到编程这两个字就认为Markdown是多么的复杂,其实它只是一种极其简单的标记语言,你只需要十多分钟就能学会;

Markdown的意义

  • 使用简单,兼容性强,只需要文本编辑器即可编写
  • 极其简单易学,很好可读性
  • 可以更专注于文章编写,不用过多考虑排版
  • 方便格式转换,很容易转换为html、pdf等

  写博客时你需在本地word写好然后复制到你博客站点中还要调整格式,现在虽然很多富文本编辑器说是支持复制word文章,不过我用过不少都不好用,复制上去后往往还要调整很多格式、布局,而当你使用Markdown就完全不存在这个问题,文本复制上去的效果和本地完全一样;

像编程一样写文章

标题

# 一级标题
## 二级标题
### 三级标题
####四级标题
#####五级标题
######六级标题

列表

无序列表,可以使用-、+、*
- 1
- 2
- 3

+ 1
+ 2
+ 3

*  1
*  2
*  3
有序列表数字加英文点
1.
2.
3.

引用

> 引用格式

斜体、粗体

*斜体*
**粗体**

分割线

可以使用三个或以上的 -、_ 、* 来建分割线
---
___
***

链接

inline链接
[链接名称](http://www.solinx.co "提示")

reference链接
[Solinx][id]
[id]: http://www.solinx.co "solinx"

图片

inline图片
![Alt Text ](/path/xxx.jpg "imageName")

reference图片
![Alt Text][id]
[id]: path/xxx/jpg "imageName"    

代码区域

缩进四个空格或一个制表符

行内代码

使用 `  反引号 扩起来
`System.out.println("")`

Markdown扩展

Markdown还衍生出了不少增强版本:Markdown Extra、MultiMarkdown、 Maruku、Github扩展等,不过如果只是用于写文章排版那只需学原生Markdown版本主够了;

并发模型—共享内存模型(线程与锁)示例篇

  共享内存模型,顾名思义就是通过共享内存来实现并发的模型,当多个线程在并发执行中使用共享资源时如不对所共享的资源进行约定或特殊处理时就会出现读到脏数据、无效数据等问题;而为了决解共享资源所引起的这些问题,Java中引入了同步、锁、原子类型等这些用于处理共享资源的操作;
  在本篇文章中,将通过几个Demo来介绍Java的synchronized、lock、atomic相关类等,Java的共享内存并发模型也就体现在同步(synchronized)、锁(lock)等这些实现上;

同步:

  Demo中开启两个线程调用一个计数器,这时计数器成了两个线程的共享资源,两个线程都在竞争共享资源发生了竟态条件,当不对竟态条件进行处理时得到的数据就可能是有异常的不正确的;

计数器Counter类

/**
 * Created by linx on 2015-05-12.
 */
public class Counter {

    private int count = 0;

    public  void increment() {
        ++count;
    }

    public int getCount() {
        return count;
   }
}
/**
 * Created by linx on 2015-05-12.
 */
public class CountThread extends Thread {
    private Counter counter;
    public CountThread(Counter counter) {
        this.counter = counter;
    }
    @Override
    public void run() {
      for(int i = 0; i &lt 5000; i++){
         counter.increment();
      }
   }
}
/**
 * Created by linx on 2015-05-12.
 */
public class CountMain {

    public static void main(String[] args) throws InterruptedException {

        Counter counter = new Counter();
        AtomicCounter atomicCounter=new AtomicCounter();
        CountThread t1 = new CountThread(counter);
        CountThread t2 = new CountThread(counter);
        t1.start();
        t2.start(); 
        t1.join();
        t2.join();
        System.out.println(counter.getCount());
    } 
}

我在执行这代码的时候几乎每次得到的结果都是不一样的,结果如下:
enter image description here

因为这里有竟态条件所以结果是不可预测的,解决竟态条件的方法是对锁竞争的资源进行加锁同步,在java中可以用synchronized或lock等锁; 现在我们再修改计数器的代码:

public synchronized void increment() {
        ++count;
    }

这里我们只是在increment方法声明处加了synchronized关键字,这时候我们在执行程序,现在每次我们得到结果都会是10000, 因为我们解决了竟态条件,同一时间就会有一个线程会进入到increment方法执行,所以这时候得到的就是正确的结果;
enter image description here

在这里我们只是把上面Demo中的synchronized换成Lock对象,得到的结果还是相同的;

/**
 * Created by linx on 2015-05-12.
 */
public class Counter {
    private int count = 0;
    Lock lock=new ReentrantLock();
    public  void increment() {
        lock.lock();
        try {
            ++count;
        }finally {
            lock.unlock();
        }
    }
    public int getCount() {
        return count;
    }
}   
   

这里我们显示的使用了显试的ReentrantLock锁对象给increment方法中的代码块进行了加锁,其他synchronized也是对方法进行了加锁,不过它使用的是对象的内置锁;

原子类型

我们上面的Demo只所以没有同步或加锁时会出现问题是因为++count不是原子的,它其实是read-modify-write三个操作,只要能保证increment为原子方法那么这里也就不是出现问题了,现在我们吧count改为原子类型;

/**
 * Created by linx on 2015-05-12.
 */
public class AtomicCounter {
    private AtomicInteger count=new AtomicInteger();
    public  void increment() {
        count.incrementAndGet();
    } 
    public AtomicInteger getCount() {
        return count;
    }
}

这个计数器类我们不进行任何同步或加锁都不会出现问题,因为increment方法是原子的。

模型优缺点

  优点:内存共享模型或称线程与锁模型使用面很广,而且现在几乎每个操作系统中也存在这种模型,所以也算非常见的一种模型。

  缺点:线程与锁模型存在的一些问题有,没有直接支持并发、无法或难于实现分布式共享内存的系统,线程与锁模型有非常不好的地方就是难于测试,在多线程编程中很多时候不经意间就出现问题了这时都还不知道,而且当突然出现了Bug这时往往我们也难于重现这个Bug,共享内存模型又是不可建立数学模型的,其中有很大的不确定性,而不确定性就说明可能掩藏着问题,人的思维也只是单线程的;

还有由于创建线程也是非常消耗资源的,而多线程间的竟态条件、锁等竞争如果处理不好也是会非常影响性能的;