并发同步知多少
2016-02-28 10:50:49 | 来源:玩转帮会 | 投稿:佚名 | 编辑:dations

原标题:并发同步知多少

  找工作的时候是否经常看到要求有高并发,分布式系统的开发设计经验,或者高并发,分布式系统的开发设计经验者优先等字样,这时候情不自禁的搜索一下什么是并发,多少算高并发,再思索一下自己的经历哪些是符合这个要求的?那么什么是并发,开发中的并发是怎么处理的,简单了解一下吧。

在介绍并发之前我们先了解一下串行和并行:

热闹的景点,买票人很多,这时只有一个窗口售票,大家排队依次买票就可以理解为串行。

排队人太多了,旁边又加开了几个窗口,多人在不同的窗口同时买票可以理解为并行。

如果只能开一个窗口,这时好多着急的人围上来,有问价格的,有掏钱的,又有取票的,在这个过程中售票员在同时应对多个买票人,可以理解为并发。

我们经常在计算机上一边听歌一边写文档(或者处理其他的事情),这就是一种并发行为,表面看两个程序是同时进行,为什么不是并行呢?计算机只有一个CPU所以只能支持一个线程运行。有人拍砖说:我家里计算机是多核CPU可以同时支持多个线程运行,确实是这样,为此我也特地去百度了一下有如下几点认知:

1、虽然是多核CPU但是,系统总线,内存是共用的,在加载内存数据时仍然需要串行访问。

2、目前的程序设计语言仍然是过程型开发,没有和好的方法能自动的切割任务使并行计算。

3、操作系统在线程调度时随着内核的增加复杂性递增,目前最多支持8核

所以基于以上认知,我们在讨论并发和同步这个问题时仍然按照CPU单核来讨论。

那么计算机是如何做到一边播放歌曲一边支持文档编辑呢?操作系统会把CPU的执行时间划分微妙级别的时间片段,每一个时间片内去调度一个线程执行,多个线程不断的切换执行,因此在人类可感知的时间段(秒级)内线程是同时执行的,所以多个线程在某个时间段内的同时执行就是并发。

串行、并行和并发如下图所示:

互联网应用基本上都是支持多用户多请求同时访问服务器端的,所以互联网应用都是支持并发的,那么高并发的主要困难是什么呢?操作系统会给每个线程分配独立的内存空间和时间片,所以线程间是隔离的。但是如果线程访问线程外的内存空间,文件系统,输入输出设备,数据库或者其他存储设备时就会发生照片竞争,共享照片的访问必须串行,保证串行访问照片的机制就是同步,JAVA中经常使用的同步机制有synchronized关键字,java.util.concurrent.locks.Lock系列类。

  同步的场景有以下几种:

  1、线程获取同步锁,获取失败则阻塞等待

  适用场景:

  a、同步获取序列号生成器,当有其他线程获取序列号时,其他线程等待

  java代码实例:

public class SynchronizedProcessor implements Processor {
    /* (non-Javadoc)
     * @see com.sunhaojie.test.thread.Processor#process(java.lang.String)
     */
    public void process(String name) {
        System.out.println(String.format("%s开始处理,当前时间是%d", name, 
System.currentTimeMillis()));
        synchronized (this) {
            System.out.println(String.format("%s获得锁%s", name, 
this.toString()));
            try {
                System.out.println(String.format("%s开始sleep", name));
                Thread.sleep(1000);
                System.out.println(String.format("%s结束sleep", name));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(String.format("%s释放锁%s", name, 
this.toString()));
        System.out.println(String.format("%s结束处理,当前时间是%d", name, 
System.currentTimeMillis()));
    }
}

  2、线程获取同步锁,获取失败结束

  适用场景:

  a、定时任务,前一个处理线程未完成时,新线程不能获取锁则直接结束

  java代码示例:

public class LockFailCloseProcessor implements Processor {
    private static Lock lock = new ReentrantLock();
    /* (non-Javadoc)
     * @see com.sunhaojie.test.thread.Processor#process(java.lang.String)
     */
    public void process(String name) {
        System.out.println(String.format("%s开始处理,当前时间是%d", name, 
System.currentTimeMillis()));
        if (lock.tryLock()) {
            System.out.println(String.format("%s获得锁%s", name, 
this.toString()));
            try {
                System.out.println(String.format("%s开始sleep", name));
                Thread.sleep(1000);
                System.out.println(String.format("%s结束sleep", name));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.unlock();
            System.out.println(String.format("%s释放锁%s", name, 
this.toString()));
        } else {
            System.out.println(String.format("%s没有获得锁直接退出", 
name));
        }
        System.out.println(String.format("%s结束处理,当前时间是%d", name, 
System.currentTimeMillis()));
    }
}

  3、线程获取同步锁后,因为其他照片不满足暂时释放同步锁,等待唤醒

  适用场景:

  a、即使通讯中,发送者获取同步锁发现队列写满时,释放锁等待接收者读取数据

  java代码示例:

public class SynchronizedWaitWriteProcessor implements Processor {
    /**
     * 是否可读标记,false:不可读,可写 true:可读,不可写
     */
    public static int maxSize = 5;
    public static List<String> content = new ArrayList<String>();
    /* (non-Javadoc)
     * @see com.sunhaojie.test.thread.Processor#process(java.lang.String)
     */
    public void process(String name) {
        System.out.println(String.format("%s开始处理,当前时间是%d", name, 
System.currentTimeMillis()));
        synchronized (content) {
            System.out.println(String.format("%s获得锁%s", name, 
this.toString()));
            try {
                if (content.size() == maxSize) {
                    System.out.println(
String.format("%s临时释放锁%s", name, this.toString()));
                    content.wait();
                }
                System.out.println(
String.format("%s开始写入信息", name));
                Random random = new Random();
                for (int i = 0; i < maxSize; i++) {
                    content.add(
String.format("写入信息%d", random.nextInt(1000)));
                }
                System.out.println(
String.format("%s结束写入信息", name));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            content.notify();
        }
        System.out.println(String.format("%s释放锁%s", name, 
this.toString()));
        System.out.println(String.format("%s结束处理,当前时间是%d", name, 
System.currentTimeMillis()));
    }
}

  4、线程获取同步锁后,因为其他照片不满足结束线程

  适用场景:

  a、即使通讯中,接收者获取同步锁发现队列无数据时,释放锁结束线程

  java代码示例:

public class SynchronizedWaitReadProcessor implements Processor {
    /* (non-Javadoc)
     * @see com.sunhaojie.test.thread.Processor#process(java.lang.String)
     */
    public void process(String name) {
        System.out.println(String.format("%s开始处理,当前时间是%d", name, 
System.currentTimeMillis()));
        synchronized (SynchronizedWaitWriteProcessor.content) {
            System.out.println(String.format("%s获得锁%s", name, 
this.toString()));
            if (SynchronizedWaitWriteProcessor.content.size() 
!= 0) {
                System.out.println(
String.format("%s开始读出信息", name));
                for (int i = 0; 
i < SynchronizedWaitWriteProcessor.content.size(); i++) {
                    System.out.println("读出信息:" + SynchronizedWaitWriteProcessor.content.get(i));
                }
                System.out.println(
String.format("%s结束读出信息", name));
            }
            SynchronizedWaitWriteProcessor.content.notify();
        }
        System.out.println(String.format("%s释放锁%s", name, 
this.toString()));
        System.out.println(String.format("%s结束处理,当前时间是%d", name, 
System.currentTimeMillis()));
    }
}

  最后送上运行以上程序的main方法和Processor 接口类:

public interface Processor {
    public void process(String name);
}
public class ThreadTest {
    public static void main(String[] args) throws InterruptedException {
        //测试SynchronizedProcessor
        //        Processor processor = new SynchronizedProcessor();
        //        for (int i = 0; i < 10; i++) {
        //            ProcessorThread threadProcessor = 
new ProcessorThread("name" + i, processor);
        //            threadProcessor.start();
        //        }
        //测试LockProcessor
        //        Processor processor = new LockProcessor();
        //        for (int i = 0; i < 10; i++) {
        //            ProcessorThread threadProcessor = 
new ProcessorThread("name" + i, processor);
        //            threadProcessor.start();
        //        }
        // Processor processor = new LockFailCloseProcessor();
        // for (int i = 0; i < 10; i++) {
        // ProcessorThread threadProcessor = 
new ProcessorThread("name" + i,
        // processor);
        // threadProcessor.start();
        // }
        Processor readProcessor = new SynchronizedWaitReadProcessor();
        ProcessorThread readThreadProcessor = 
new ProcessorThread("read", readProcessor);
        readThreadProcessor.start();
        Processor writeProcessor = new SynchronizedWaitWriteProcessor();
        ProcessorThread writeThreadProcessor = 
new ProcessorThread("write", writeProcessor);
        writeThreadProcessor.start();
        Thread.sleep(100);
        ProcessorThread read2ThreadProcessor = 
new ProcessorThread("read2", readProcessor);
        read2ThreadProcessor.start();
    }
}

  多线程可以大大提高性能,但是多线程的同步又增加了应用的复杂性,是否能平衡多线程的性能和复杂性是是否有高并发经验的要求。

tags:

上一篇  下一篇

相关:

JavaScript中call,apply,bind方法的总结

  why?call,apply,bind干什么的?为什么要学这个?   一般用来指定this的环境,在没有学之前,通常会

街友失志不工作 警掏钱请他扫马路

40岁何姓街友,原本在桃园工地工作,日前遭工头责备态度不积极,又与同事相处不愉快,最后愤而离职,但家人

工作满档健康亮红灯 女神哈妮宣布停工1个月

大势女团“EXID”超人气成员、韩国新生代女神哈妮,从“电臀舞”到认爱“JYJ”金俊秀,不仅知名度冲到高点,

整合型行动应用方案发表 可连结企业E化系统

科技中心/台北报道现代人的数位生活从电脑转移到手机上,同样对于企业而言,也在研究以行动化的数位工具加

四点解剖:高德地图保持高速增长的背后的产品逻辑

最近,高德地图宣布截止到2016年1月底,高德地图移动端用户数已超过5亿,2015年移动端活跃用户增长超过100%

我的专业是人类学,平时会去部落里当个女王啥的(误)

人类学分支太多我只能说自己学的社会文化人类学。本想着自己本科不是人类学,目前只读了一年人类学的硕士课

有家公司要帮外国人在美国办银行卡,但它只在乎创业者

对非美国创业者而言,要想把在线生意做到美国市场,并没那么容易。除了要一个个对接当地的支付服务,还有大

JavaScript中this指针指向的彻底理解

首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,

带你进入AngularJS的大门

介绍这是我写的第一篇关于Angular.js的文章,但是我确信看完这篇文章将对你了解Angular.js的基本知识有很大

什么广告最能打动你?也是有科学测量法的

今年哪个超级碗广告引起人们情感共鸣最多?伦敦的一家创意公司 Brave 用科学方法在 24 个观众中做了一次广告

站长推荐: