共享内存的情况下,出现的高并发异常

package thread;

public class TestShareMemory {

    static String shareM = "";
    static void alter(String tmp){
        shareM = tmp;
    }

    static class GThread extends Thread {
           public void run() {
                for (int i = 1; i < 2222122; i++){
                    alter("GThread");
                    if("XThread".equals(shareM)){
                    System.out.println("GThread:"+shareM);}
                }

            }
     }

     static class XThread extends Thread {
           public void run() {
                for (int i = 1; i < 2221222; i++){
                    alter("XThread");
                    if("GThread".equals(shareM)){
                    System.out.println("XThread:"+shareM);}
                }

            }
     }

    public static void main(String[] args) {

        Thread p2 = new XThread();
        Thread p1 = new GThread();
         p1.start();
         p2.start();
    }

}

普通情况下,是不会出现“GThread:XThread” 这种情况的,但是在上述高并发,并且共享内存的情况下就可能出现问题!

可以通过这样加锁:

package thread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestShareMemory {

    private static Lock lock = new ReentrantLock();
    static String shareM = "";

    static void alter(String tmp) {
        shareM = tmp;
    }

    static class GThread extends Thread {
        public void run() {
            for (int i = 1; i < 2222122; i++) {
                lock.lock();// 显示加锁
                try {
                    alter("GThread");
                    if ("XThread".equals(shareM)) {
                        System.out.println("GThread:" + shareM);
                    }
                } finally {
                    // 显示释放锁
                    lock.unlock();
                }

            }

        }
    }

    static class XThread extends Thread {
        public void run() {
            for (int i = 1; i < 2221222; i++) {
                lock.lock();// 显示加锁
                try {
                    alter("XThread");
                    if ("GThread".equals(shareM)) {
                        System.out.println("XThread:" + shareM);
                    }
                } finally {
                    // 显示释放锁
                    lock.unlock();
                }
            }

        }
    }

    public static void main(String[] args) {

        Thread p2 = new XThread();
        Thread p1 = new GThread();
        p1.start();
        p2.start();
    }

}

总结:在高并发并且有共享内存的情况下,有几个方法解决并发问题:

1、把共享内存的变量变成线程内部的变量。(有时候是没必要线程共享变量)。

2、在必要线程共享变量的时候,对涉及到的读写共享变量的地方加锁。

时间: 2024-11-05 22:17:10

共享内存的情况下,出现的高并发异常的相关文章

解决java读取大文件内存溢出问题、如何在不重复读取与不耗尽内存的情况下处理大文件

1.传统的在内存中读取 读取文件行的标准方式是在内存中读取,Guava 和Apache Commons IO都提供了如下所示快速读取文件行的方法: 1 2 3 Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path)); 这种方法带来的问题是文件的所有行都被存放在内存中,当文件足够大时很快就会导致程序抛出OutOfMemoryError 异常. 例如:读取一个大约1G的文件: 1 2 3

高并发情况下Linux系统及kernel参数优化

众所周知在默认参数情况下Linux对高并发支持并不好,主要受限于单进程最大打开文件数限制.内核TCP参数方面和IO事件分配机制等.下面就从几方面来调整使Linux系统能够支持高并发环境. Iptables相关 如非必须,关掉或卸载iptables防火墙,并阻止kernel加载iptables模块.这些模块会影响并发性能. 单进程最大打开文件数限制 一般的发行版,限制单进程最大可以打开1024个文件,这是远远不能满足高并发需求的,调整过程如下: 在#号提示符下敲入: # ulimit–n 6553

Unix IPC之基于共享内存的计数器

目的 本文主要实现一个基于共享内存的计数器,通过父子进程对其访问. 本文程序需基于<<Unix网络编程-卷2>>的环境才能运行.程序中大写开头的函数为其小写同名函数的包裹函数,增加了错误处理信息. 1 函数介绍 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <sys/mman> /**  * Map addresses starting near ADDR an

构建高并发高可用的电商平台架构实践(下)

构建高并发高可用的电商平台架构实践(下) 6. 数据存储 数据库存储大体分为以下几类,有关系型(事务型)的数据库,以oracle.mysql为代表,有keyvalue数据库,以redis和memcached db为代表,有文档型数据库如mongodb,有列式分布式数据库以HBase,cassandra,dynamo为代表,还有其他的图形数据库.对象数据 库.xml数据库等.每种类型的数据库应用的业务领域是不一样的,下面从内存型.关系型.分布式三个维度针对相关的产品做性能可用性等方面的考量分析.

PHP共享内存的应用shmop系列

简单的说明 可能很少情况会使用PHP来操控共享内存,一方面在内存的控制上,MC已经提供了一套很好的方式,另一方面,自己来操控内存的难度较大,内存的读写与转存,包括后面可能会用到的存储策略,要是没有一定计算机组成原理的基础,想做这些不是一件容易的事情.那为什么还要使用它呢?如果我想进行管道通信,为其它的应用服务准备数据:我想建立自己的数据缓存体系,使用MC有点大炮打苍蝇的感觉.那么shmop会是一个选择,当然,在操作内存前,一定要谨慎. 系统要求 shmop系列函数只是在unix/Linux下可用

(转)Linux环境进程间通信系列(五):共享内存

原文地址:http://www.cppblog.com/mydriverc/articles/29741.html 共享内存可以说是最有用的进程间通信方式,也是最快的 IPC 形式.两个不同进程 A . B 共享内存的意思是,同一块物理内存被映射到进程 A . B 各自的进程地址空间.进程 A 可以即时看到进程 B 对共享内存中数据的更新,反之亦然.由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以. 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存

PHP 共享内存使用与信号控制

共享内存 共享内存的使用主要是为了能够在同一台机器不同的进程中共享一些数据,比如在多个 php-fpm 进程中共享当前进程的使用情况.这种通信也称为进程间通信(Inter-Process Communication),简称 IPC. PHP 内置的 shmop 扩展 (Shared Memory Operations) 提供了一系列共享内存操作的函数(可能是用的人不多吧,这一块儿的文档还没有中文翻译).在 Linux 上,这些函数直接是通过调用 shm* 系列的函数实现,而 Winodows 上

Linux进程间通信--mmap()共享内存(二)

内核怎样保证各个进程寻址到同一个共享内存区域的内存页面 1.page cache及swap cache中页面的区分:一个被访问文件的物理页面都驻留在page cache或swap cache中,一个页面的所有信息由struct page来描述.struct page中有一个域为指针mapping ,它指向一个struct address_space类型结构.page cache或swap cache中的所有页面就是根据address_space结构以及一个偏移量来区分的. 2.文件与addres

Oracle Study之--IPCS管理共享内存

Oracle Study之--IPCS管理共享内存 Unix/linux下的共享内存.信号量.队列信息管理 在unix/linux下,经常有因为共享内存.信号量,队列等共享信息没有干净地清除而引起一些问题. 查看共享信息的内存的命令是:ipcs [-m|-s|-q]. 默认会列出共享内存.信号量,队列信息 -m列出共享内存 -s列出共享信号量 -q列出共享队列 清除命令是:ipcrm [-m|-s|-q] id. -m 删除共享内存 -s删除共享信号量 -q删除共享队列. 案例分析: [[ema