Apache Shiro Reference Documentation

  1. Overview
  2. Core
  3. Spring-based Applications

1.Overview

  1. pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>
    <groupId>org.apache.shiro.tutorials</groupId>
    <artifactId>shiro-tutorial</artifactId>
    <version>1.0.0</version>
    <name>First Apache Shiro Application</name>
    <packaging>jar</packaging> <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties> <build>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.0.2</version>
    <configuration>
    <source>1.8</source>
    <target>1.8</target>
    <encoding>${project.build.sourceEncoding}</encoding>
    </configuration>
    </plugin> <!-- This plugin is only to test run our little application. It is not
    needed in most Shiro-enabled applications: -->
    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.1</version>
    <executions>
    <execution>
    <goals>
    <goal>java</goal>
    </goals>
    </execution>
    </executions>
    <configuration>
    <classpathScope>test</classpathScope>
    <mainClass>Tutorial</mainClass>
    </configuration>
    </plugin>
    </plugins>
    </build> <dependencies>
    <dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.3.2</version>
    </dependency>
    <!-- Shiro uses SLF4J for logging. We'll use the 'simple' binding
    in this example app. -->
    <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.6.1</version>
    <scope>test</scope>
    </dependency>
    </dependencies> </project>
  2. src\main\resources\shiro.ini
    # =============================================================================
    # Tutorial INI configuration
    #
    # Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :)
    # ============================================================================= # -----------------------------------------------------------------------------
    # Users and their (optional) assigned roles
    # username = password, role1, role2, ..., roleN
    # -----------------------------------------------------------------------------
    [users]
    root = secret, admin
    agror = agror, goodguy, schwartz
    guest = guest, guest
    presidentskroob = 12345, president
    darkhelmet = ludicrousspeed, darklord, schwartz
    lonestarr = vespa, goodguy, schwartz # -----------------------------------------------------------------------------
    # Roles with assigned permissions
    # roleName = perm1, perm2, ..., permN
    # -----------------------------------------------------------------------------
    [roles]
    admin = *
    schwartz = lightsaber:*
    goodguy = winnebago:drive:eagle5
  3. src\main\java\Tutorial.java
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.Subject;
    import org.apache.shiro.util.Factory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory; public class Tutorial { private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class); public static void main(String[] args) {
    log.info("My First Apache Shiro Application"); //1.
    Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini"); //2.
    SecurityManager securityManager = factory.getInstance(); //3.
    SecurityUtils.setSecurityManager(securityManager); //4.
    Subject currentUser = SecurityUtils.getSubject();
    //Session session = currentUser.getSession();
    //session.setAttribute( "someKey", "aValue" );
    //session.setAttribute( "argor", "argor" ); //5.
    // Login
    if ( !currentUser.isAuthenticated() ) {
    //collect user principals and credentials in a gui specific manner
    //such as username/password html form, X509 certificate, OpenID, etc.
    //We'll use the username/password example here since it is the most common.
    //UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
    UsernamePasswordToken token = new UsernamePasswordToken("agror", "agror"); //this is all you have to do to support 'remember me' (no config - built in!):
    token.setRememberMe(true); try {
    currentUser.login( token );
    //if no exception, that's it, we're done! //print their identifying principal (in this case, a username):
    log.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." ); //6.
    TestAuthorization( currentUser );
    } catch ( UnknownAccountException uae ) {
    //username wasn't in the system, show them an error message?
    } catch ( IncorrectCredentialsException ice ) {
    //password didn't match, try again?
    } catch ( LockedAccountException lae ) {
    //account for that username is locked - can't login. Show them a message?
    } catch ( AuthenticationException ae ) {
    //unexpected condition - error?
    } finally {
    log.info( "User login status: [- " + currentUser.isAuthenticated() + " -]." ); // Logout
    currentUser.logout();
    //removes all identifying information and invalidates their session too.
    }
    } System.exit(0);
    } private static void TestAuthorization ( Subject currentUser ) {
    //6.
    // We can also test to see if they have specific role or not:
    if ( currentUser.hasRole( "schwartz" ) ) {
    log.info( currentUser.getPrincipal() + " May the Schwartz be with you!" );
    } else {
    log.info( currentUser.getPrincipal() + " , mere mortal, has't schwartz." );
    } if ( currentUser.hasRole( "goodguy" ) ) {
    log.info( currentUser.getPrincipal() + " May the goodguy be with you!" );
    } else {
    log.info( currentUser.getPrincipal() + " , mere mortal, has't goodguy." );
    } if ( currentUser.hasRole( "admin" ) ) {
    log.info( currentUser.getPrincipal() + " May the admin be with you!" );
    } else {
    log.info( currentUser.getPrincipal() + " , mere mortal, has't admin." );
    } // We can also see if they have a permission to act on a certain type of entity:
    if ( currentUser.isPermitted( "lightsaber:weild" ) ) {
    log.info("You may use a lightsaber ring.");
    } else {
    log.info("Sorry, lightsaber rings are for schwartz masters only.");
    }
    // Also, we can perform an extremely powerful instance-level permission
    // check - the ability to see if the user has the ability to access a
    // specific instance of a type:
    if ( currentUser.isPermitted( "winnebago:drive:eagle5" ) ) {
    log.info("You are permitted to 'drive' the 'winnebago' with license plate (id) 'eagle5'. " +
    "Here are the keys - have fun!");
    } else {
    log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
    }
    }
    }
  4. run
    E:\Users\Administrator\Desktop\shiro\shiro-tutorial>mvn compile exec:java
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] Building First Apache Shiro Application 1.0.0
    [INFO] ------------------------------------------------------------------------
    [INFO]
    [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ shiro-tutorial ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] Copying 1 resource
    [INFO]
    [INFO] --- maven-compiler-plugin:2.0.2:compile (default-compile) @ shiro-tutorial ---
    [INFO] Compiling 1 source file to E:\Users\Administrator\Desktop\shiro\shiro-tutorial\target\classes
    [INFO]
    [INFO] >>> exec-maven-plugin:1.1:java (default-cli) > validate @ shiro-tutorial >>>
    [INFO]
    [INFO] <<< exec-maven-plugin:1.1:java (default-cli) < validate @ shiro-tutorial <<<
    [INFO]
    [INFO] --- exec-maven-plugin:1.1:java (default-cli) @ shiro-tutorial ---
    0 [Tutorial.main()] INFO Tutorial - My First Apache Shiro Application
    47 [Tutorial.main()] INFO Tutorial - User login status: [- false -]. E:\Users\Administrator\Desktop\shiro\shiro-tutorial>mvn compile exec:java
    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------------------------------------------------------------
    [INFO] Building First Apache Shiro Application 1.0.0
    [INFO] ------------------------------------------------------------------------
    [INFO]
    [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ shiro-tutorial ---
    [INFO] Using 'UTF-8' encoding to copy filtered resources.
    [INFO] Copying 1 resource
    [INFO]
    [INFO] --- maven-compiler-plugin:2.0.2:compile (default-compile) @ shiro-tutorial ---
    [INFO] Compiling 1 source file to E:\Users\Administrator\Desktop\shiro\shiro-tutorial\target\classes
    [INFO]
    [INFO] >>> exec-maven-plugin:1.1:java (default-cli) > validate @ shiro-tutorial >>>
    [INFO]
    [INFO] <<< exec-maven-plugin:1.1:java (default-cli) < validate @ shiro-tutorial <<<
    [INFO]
    [INFO] --- exec-maven-plugin:1.1:java (default-cli) @ shiro-tutorial ---
    0 [Tutorial.main()] INFO Tutorial - My First Apache Shiro Application
    31 [Tutorial.main()] INFO org.apache.shiro.session.mgt.AbstractValidatingSessionManager - Enabling session validation scheduler...
    109 [Tutorial.main()] INFO Tutorial - User [agror] logged in successfully.
    109 [Tutorial.main()] INFO Tutorial - agror May the Schwartz be with you!
    109 [Tutorial.main()] INFO Tutorial - agror May the goodguy be with you!
    109 [Tutorial.main()] INFO Tutorial - agror , mere mortal, has't admin.
    109 [Tutorial.main()] INFO Tutorial - You may use a lightsaber ring.
    109 [Tutorial.main()] INFO Tutorial - You are permitted to 'drive' the 'winnebago' with license plate (id) 'eagle5'. Here are the keys - have fun!
    109 [Tutorial.main()] INFO Tutorial - User login status: [- true -].

    第一次执行时,使用一个错误的密码;第二次执行使用正确的密码;

2.Core

  1. Authentication
    1. Authenticating Subjects
      Step 1: Collect the Subject’s principals and credentials

      //Example using most common scenario of username/password pair:
      UsernamePasswordToken token = new UsernamePasswordToken(username, password); //"Remember Me" built-in:
      token.setRememberMe(true);

      Step 2: Submit the principals and credentials

      Subject currentUser = SecurityUtils.getSubject();
      currentUser.login(token);

      Step 3: Handling Success or Failure

      try {
      currentUser.login(token);
      } catch ( UnknownAccountException uae ) { ...
      } catch ( IncorrectCredentialsException ice ) { ...
      } catch ( LockedAccountException lae ) { ...
      } catch ( ExcessiveAttemptsException eae ) { ...
      } ... catch your own ...
      } catch ( AuthenticationException ae ) {
      //unexpected error?
      }

      <Login Failure Tip> The security best practice is to only show a generic failure message , for example, "Incorrect username or password".

    2. Logging Out
      currentUser.logout(); //removes all identifying information and invalidates their session too.
  2. Authorization
    1. Understanding Permissions in Apache Shiro
      Wildcard Permissions & Checking Permissions

      Simple Usage
      subject.isPermitted("sshdStart")
      subject.isPermitted("sshdStop")
      subject.isPermitted("sshdRestart") Multiple Parts
      subject.isPermitted("sshd:start")
      subject.isPermitted("sshd:stop")
      subject.isPermitted("sshd:restart") Multiple Values
      subject.isPermitted("sshd:start,stop,restart")
      subject.isPermitted("sshd:*") Instance-Level Access Control
      subject.isPermitted("sshd:start:root")
      subject.isPermitted("sshd:*:root")
      subject.isPermitted("sshd:*:*") Missing Parts
      subject.isPermitted("sshd:start:")//is equivalent to below
      subject.isPermitted("sshd:start:*")
      subject.isPermitted("sshd")//is equivalent to below
      subject.isPermitted("sshd:*:*")
    2. Elements of Authorization
      ♠Permission statements reflect behavior (actions associated with resource types) only.
      ♠A Role is a named entity that typically represents a set of behaviors or responsibilities.
      ♠A user essentially is the ‘who’ of an application. As we’ve covered previously however, the Subject is really Shiro’s ‘User’ concept.
    3. Authorizing Subjects
      • ♠Programmatically
        Role-Based Authorization

        Subject currentUser = SecurityUtils.getSubject();
        
        if (currentUser.hasRole("administrator")) {
        //show the admin button
        } else {
        //don't show the button? Grey it out?
        }

        Permission-Based Authorization

        Permission printPermission = new PrinterPermission("laserjet4400n", "print");
        
        Subject currentUser = SecurityUtils.getSubject();
        
        if (currentUser.isPermitted(printPermission)) {
        //show the Print button
        } else {
        //don't show the button? Grey it out?
        }
        Subject currentUser = SecurityUtils.getSubject();
        
        if (currentUser.isPermitted("printer:print:laserjet4400n")) {
        //show the Print button
        } else {
        //don't show the button? Grey it out?
        }
        Subject currentUser = SecurityUtils.getSubject();
        
        Permission p = new WildcardPermission("printer:print:laserjet4400n");
        
        if (currentUser.isPermitted(p) {
        //show the Print button
        } else {
        //don't show the button? Grey it out?
        }
      • ♠JDK annotations( <need> to enable AOP support in your application)
        The RequiresAuthentication annotation
        @RequiresAuthentication
        public void updateAccount(Account userAccount) {
        //this method will only be invoked by a
        //Subject that is guaranteed authenticated
        ...
        }
        //This is mostly equivalent to the following Subject-based logic: public void updateAccount(Account userAccount) {
        if (!SecurityUtils.getSubject().isAuthenticated()) {
        throw new AuthorizationException(...);
        } //Subject is guaranteed authenticated here
        ...
        }

        The RequiresGuest annotation

        @RequiresGuest
        public void signUp(User newUser) {
        //this method will only be invoked by a
        //Subject that is unknown/anonymous
        ...
        }
        //This is mostly equivalent to the following Subject-based logic: public void signUp(User newUser) {
        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        if (principals != null && !principals.isEmpty()) {
        //known identity - not a guest:
        throw new AuthorizationException(...);
        } //Subject is guaranteed to be a 'guest' here
        ...
        }

        The RequiresPermissions annotation

        @RequiresPermissions("account:create")
        public void createAccount(Account account) {
        //this method will only be invoked by a Subject
        //that is permitted to create an account
        ...
        }
        //This is mostly equivalent to the following Subject-based logic: public void createAccount(Account account) {
        Subject currentUser = SecurityUtils.getSubject();
        if (!subject.isPermitted("account:create")) {
        throw new AuthorizationException(...);
        } //Subject is guaranteed to be permitted here
        ...
        }

        The RequiresRoles permission

        @RequiresRoles("administrator")
        public void deleteUser(User user) {
        //this method will only be invoked by an administrator
        ...
        }
        //This is mostly equivalent to the following Subject-based logic: public void deleteUser(User user) {
        Subject currentUser = SecurityUtils.getSubject();
        if (!subject.hasRole("administrator")) {
        throw new AuthorizationException(...);
        } //Subject is guaranteed to be an 'administrator' here
        ...
        }

        The RequiresUser annotation

        @RequiresUser
        public void updateAccount(Account account) {
        //this method will only be invoked by a 'user'
        //i.e. a Subject with a known identity
        ...
        }
        This is mostly equivalent to the following Subject-based logic: public void updateAccount(Account account) {
        Subject currentUser = SecurityUtils.getSubject();
        PrincipalCollection principals = currentUser.getPrincipals();
        if (principals == null || principals.isEmpty()) {
        //no identity - they're anonymous, not allowed:
        throw new AuthorizationException(...);
        } //Subject is guaranteed to have a known identity here
        ...
        }

3.Integrating into Spring-based Applications

Shiro applications need an application singleton SecurityManager instance.

  1. web.xml
    Here is how to configure Shiro in a Spring-based web application:

    <!-- The filter-name matches name of a 'shiroFilter' bean inside applicationContext.xml -->
    <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
    <param-name>targetFilterLifecycle</param-name>
    <param-value>true</param-value>
    </init-param>
    </filter> ... <!-- Make sure any request you want accessible to Shiro is filtered. /* catches all -->
    <!-- requests. Usually this filter mapping is defined first (before all others) to -->
    <!-- ensure that Shiro works in subsequent filters in the filter chain: -->
    <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
  2. applicationContext.xml
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <!-- override these for application-specific URLs if you like:
    <property name="loginUrl" value="/login.jsp"/>
    <property name="successUrl" value="/home.jsp"/>
    <property name="unauthorizedUrl" value="/unauthorized.jsp"/> -->
    <!-- The 'filters' property is not necessary since any declared javax.servlet.Filter bean -->
    <!-- defined will be automatically acquired and available via its beanName in chain -->
    <!-- definitions, but you can perform instance overrides or name aliases here if you like: -->
    <!-- <property name="filters">
    <util:map>
    <entry key="anAlias" value-ref="someFilter"/>
    </util:map>
    </property> -->
    <property name="filterChainDefinitions">
    <value>
    # some example chain definitions:
    /admin/** = authc, roles[admin]
    /docs/** = authc, perms[document:read]
    /** = authc
    # more URL-to-FilterChain definitions here
    </value>
    </property>
    </bean> <!-- Define any javax.servlet.Filter beans you want anywhere in this application context. -->
    <!-- They will automatically be acquired by the 'shiroFilter' bean above and made available -->
    <!-- to the 'filterChainDefinitions' property. Or you can manually/explicitly add them -->
    <!-- to the shiroFilter's 'filters' Map if desired. See its JavaDoc for more details. -->
    <bean id="someFilter" class="..."/>
    <bean id="anotherFilter" class="..."> ... </bean>
    ... <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <!-- Single realm app. If you have multiple realms, use the 'realms' property instead. -->
    <property name="realm" ref="myRealm"/>
    <!-- By default the servlet container sessions will be used. Uncomment this line
    to use shiro's native sessions (see the JavaDoc for more): -->
    <!-- <property name="sessionMode" value="native"/> -->
    </bean>
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- Define the Shiro Realm implementation you want to use to connect to your back-end -->
    <!-- security datasource: -->
    <bean id="myRealm" class="...">
    ...
    </bean>
  3. Enabling Shiro Annotations
    Here is how to enable these annotations. Just add these two bean definitions to applicationContext.xml:
    <!-- Enable Shiro Annotations for Spring-configured beans.  Only run after -->
    <!-- the lifecycleBeanProcessor has run: -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager"/>
    </bean>

.

official shiro(Reference Manual)的更多相关文章

  1. Java中的原始类型(Primitive Types)与引用类型(Reference Values)

    Java虚拟机可以处理的类型有两种,一种是原始类型(Primitive Types),一种是引用类型(Reference Types). 与之对应,也存在有原始值(Primitive Values)和 ...

  2. C#中的值类型(value type)与引用类型(reference type)的区别

    ylbtech- .NET-Basic:C#中的值类型与引用类型的区别 C#中的值类型(value type)与引用类型(reference type)的区别 1.A,相关概念返回顶部     C#中 ...

  3. (20)Cocos2d-x中的引用计数(Reference Count)和自动释放池(AutoReleasePool)

    引用计数 引用计数是c/c++项目中一种古老的内存管理方式.当我8年前在研究一款名叫TCPMP的开源项目的时候,引用计数就已经有了. iOS SDK把这项计数封装到了NSAutoreleasePool ...

  4. 【转】 C++易混知识点4: 自己编写一个智能指针(Reference Counting)学习auto_ptr和reference counting

    这篇文章建大的介绍了如何编写一个智能指针. 介绍: 什么是智能指针?答案想必大家都知道,智能指针的目的就是更好的管理好内存和动态分配的资源,智能指针是一个智能的指针,顾名思义,他可以帮助我们管理内存. ...

  5. SpringMVC整合Shiro(配解释)

    第一步:配置web.xml ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 --> ...

  6. C++11 特性:成员函数引用限定 (Reference qualifier)

    学了这么多年C++今天拜读scott meyes的more effective cpp第一次看到这种写法... 引用限定可以让成员函数只能被左值对象调用或者只能被右值对象调用: #include &l ...

  7. 【Netty官方文档翻译】引用计数对象(reference counted objects)

    知乎有关于引用计数和垃圾回收GC两种方式的详细讲解 https://www.zhihu.com/question/21539353 原文出处:http://netty.io/wiki/referenc ...

  8. iOS项目开发中的知识点与问题收集整理②(Part 二)

    1.点击UIButton 无法产生触摸事件    如果在UIImageView中添加了一个按钮,你会发现在默认情况下这个按钮是无法被点击的,需要设置UIImageView的userInteractio ...

  9. iOS 面试大全从简单到复杂(简单篇)

    1.UIWindow和UIView和 CALayer 的联系和区别? 答:UIView是视图的基类,UIViewController是视图控制器的基类,UIResponder是表示一个可以在屏幕上响应 ...

随机推荐

  1. 读DataSnap源代码(五)

    function TDSHTTPWebDispatcher.DispatchRequest(Sender: TObject; Request: TWebRequest; Response: TWebR ...

  2. hanlp在Python环境中的安装失败后的解决方法

    Hanlp是由一系列模型与算法组成的javag工具包,目标是普及自然语言处理再生环境中的应用.有很多人在安装hanlp的时候会遇到安装失败的情况,下面就是某大神的分享的在python环境中安装失败的解 ...

  3. MS DSVM、DLVM

    DSVM(Data Science Virtual Machine 数据科学虚拟机)  是专为研究数据科学生成的 Microsoft Azure 云上的自定义 VM 映像.它预装并预配了许多热门数据科 ...

  4. 服务器病了吗? Linux 服务器的那些性能参数指标

    一个基于 Linux 操作系统的服务器运行的同时,也会表征出各种各样参数信息.通常来说运维人员.系统管理员会对这些数据会极为敏感,但是这些参数对于开发者来说也十分重要,尤其当你的程序非正常工作的时候, ...

  5. 用DDE控制Word

    DDE(Dynamic Data Exchange),称为动态数据交换.用于进程间的通讯,看看他如何来和Word交互. 在System页签下有TDdeClientConv组件,拖一个放到界面上,然后我 ...

  6. 【巷子】---flux---【react】

    一.什么是Flux Flux 是一种架构思想,专门解决软件的结构问题.它跟MVC 架构是同一类东西,但是更加简单和清晰. 二.flux的基本概念 (1) .Flux由4部分组成 1.View:视图层 ...

  7. Azure ARM (22) 使用Azure PowerShell创建Azure RM VM

    <Windows Azure Platform 系列文章目录> 在Azure China获得VM Image,可以执行下面的脚本. Get-AzureRmVMImagePublisher ...

  8. ui选型

    基本思路是风格必须适合博客风格,必须独树一帜. 选中的ui框架必须符合上述两个条件,另外,如果需要自身做一些css修改,修改量必须尽可能小. 1) 不用bootstrap的自带ui.bootstrap ...

  9. P1916小书童--大战蚂蚁

    链接 题解:(这里蚂蚁0血也算活...) #include<iostream>#include<cstdio>#include<cmath>using namesp ...

  10. java高并发编程(二)

    马士兵java并发编程的代码,照抄过来,做个记录. 一.分析下面面试题 /** * 曾经的面试题:(淘宝?) * 实现一个容器,提供两个方法,add,size * 写两个线程,线程1添加10个元素到容 ...