public interface Future<V> extends java.util.concurrent.Future<V> {
boolean isSuccess(); //当且仅当I/O操作成功完成时,返回true
boolean isCancellable(); //当且仅当可以通过cancel方法取消时,返回true
Throwable cause();//如果I/O操作失败,返回其失败原因。如果成功完成或者还未完成,返回null
//将指定的监听器添加到此Future,future完成时,会通知此监听器,如果添加监听器时future已经完成,则立即通知此监听器
Future<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);
//移除监听器,如果future已经完成,则不会触发
Future<V> removeListener(GenericFutureListener<? extends Future<? super V>> listener);
//等待此future done
Future<V> sync() throws InterruptedException;
//等待,不可中断
Future<V> syncUninterruptibly();
//等待Future完成
Future<V> await() throws InterruptedException;
//等待Future完成,不可中断
Future<V> awaitUninterruptibly();
//立即返回,如果此时future未完成,返回null
V getNow();
@Override
boolean cancel(boolean mayInterruptIfRunning);
}
/**
GOOD
*/
Bootstrap b = new Bootstrap();
b.option(ChannelOption.CONNECT_TIMEOUT_MILLS,10000);
ChannelFuture f = b.connect(...);
f.awaitUninterrputibly();
assert f.isDone();
if(f.isCancelled()){
//取消连接尝试
}else if(!f.isSuccess()){
f.cause.printstacktrace();
}else{
//连接成功
}
/**
DefaultPromise.awaitUninterruptibly()
*/
public Promise<V> awaitUninterruptibly() {
//如果已经完成,则立即返回
if (isDone()) {
return this;
}
//检查死锁
checkDeadLock();
boolean interrupted = false;
//使用同步,使修改waiter的线程只有一个
synchronized (this) {
//如果未完成一直循环检测
while (!isDone()) {
//++waiters
incWaiters();
try {
wait();
} catch (InterruptedException e) {
// Interrupted while waiting.
interrupted = true;
} finally {
//--waiters
decWaiters();
}
}
}
if (interrupted) {
Thread.currentThread().interrupt();
}
return this;
}
package java.util;
import java.io.InvalidobjectException;
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
static final long serialVersionUID = -5024744406713321676L;
private transient HashMap<E,Object> map;
// 空对象,放在map中的value位置
private static final Object PRESENT = new Object();
/**
*构造一个新的,空的HashSet,其底层 HashMap实例的默认初始容量是 16,加载因子是 0.75
*/
public HashSet() {
map = new HashMap<>();
}
/**
* 构造一个包含指定 collection 中的元素的新 set,容量为传入集合长度除以默认加载因子0.75 与默认初始化容量16的最大值
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
/**
* 构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和指定的加载因子
*/
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
/**
*构造一个新的空 set,其底层 HashMap 实例具有指定的初始容量和默认的加载因子0.75
*/
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
/**
* Constructs a new, empty linked hash set. (This package private
* constructor is only used by LinkedHashSet.) The backing
* HashMap instance is a LinkedHashMap with the specified initial
* capacity and the specified load factor.
*
* @param initialCapacity the initial capacity of the hash map
* @param loadFactor the load factor of the hash map
* @param dummy ignored (distinguishes this
* constructor from other int, float constructor.)
* @throws IllegalArgumentException if the initial capacity is less
* than zero, or if the load factor is nonpositive
*/
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
/**
* 返回对此 set 中元素进行迭代的迭代器
*/
public Iterator<E> iterator() {
return map.keySet().iterator();
}
/**
* 获取数组个数,实际上是获取底层map中数据的个数
*/
public int size() {
return map.size();
}
/**
* 判断是否为空,实际上是判断map中的size是否等于0
*/
public boolean isEmpty() {
return map.isEmpty();
}
/**
* 是都包含某元素,实际上是判断是否包含key,因为set只有单值,所map中其实只用到了key,map为空对象
*/
public boolean contains(Object o) {
return map.containsKey(o);
}
/**
*调用map的put方法,其中value值为静态的Object对象
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
/**
* 删除元素调用的是map的remove函数
*/
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
/**
* 清空集合,调用的是map的clear()
*/
public void clear() {
map.clear();
}
/**
* 返回此 HashSet 实例的浅表副本
*/
@SuppressWarnings("unchecked")
public Object clone() {
try {
HashSet<E> newSet = (HashSet<E>) super.clone();
newSet.map = (HashMap<E, Object>) map.clone();
return newSet;
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
}
class Resource{
private boolean isEmpty01 = true;
private boolean isEmpty02 = false;
private boolean isEmpty03 = false;
//每个put方法对应一个输出,每输出一个就等待,等待其他人的唤醒
public void put1(){
while(!isEmpty01){
try{
wait();
}catch(InterruptedException e){
e.printstacktrace();
}
}
//输出后
isEmpty01 = false;
isEmpty02 = true;
notifyAll();
}
public void put2(){
while(!isEmpty02){
try{
wait();
}catch(InterruptedException e){
e.printstacktrace();
}
}
isEmpty02 = false;
isEmpty03 = true;
notifyAll();
}
public void put3(){
while(!isEmpty03){
try{
wait();
}catch(InterruptedException e){
e.printstacktrace();
}
}
isEmpty03 = false;
isEmpty01 = true;
notifyAll();
}
}
class Player01 implements Runnable{
private Resource res;
private String[] arr;
Player01(){}
Player01(String[] arr,Resource res){
this.arr = arr;
this.res = res;
}
public void run(){
synchronized(res){
for(int i=0;i<arr.length;i++){
//错误的点
//61,62,这两句不能交换顺序
res.put1();
System.out.print(arr[i]+"-");
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printstacktrace();
}
}
}
}
}
class Player02 implements Runnable{
private Resource res;
private String[] arr;
Player02(){}
Player02(String[] arr,Resource res){
this.arr = arr;
this.res = res;
}
public void run(){
synchronized(res){
for(int i=0;i<arr.length;i++){
res.put2();
System.out.print(arr[i]+"-");
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printstacktrace();
}
}
}
}
}
class Player03 implements Runnable{
private Resource res;
private String[] arr;
Player03(){}
Player03(String[] arr,Resource res){
this.arr = arr;
this.res = res;
}
public void run(){
synchronized(res){
for(int i=0;i<arr.length;i++){
res.put3();
System.out.print(arr[i]+"## ");
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printstacktrace();
}
}
}
}
}
class Test08{
public static void main(String[] args){
String[] arr1 = {"1","3","5","7","9"};
String[] arr2 = {"a","b","c","d","e"};
String[] arr3 = {"2","4","6","8","0"};
Resource res = new Resource();
Player01 p1 = new Player01(arr1,res);
Player02 p2 = new Player02(arr2,res);
Player03 p3 = new Player03(arr3,res);
Thread t1 = new Thread(p1);
Thread t2 = new Thread(p2);
Thread t3 = new Thread(p3);
t1.start();
t2.start();
t3.start();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1" Metadata-complete="true">
<!-- 声明Spring的主配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/*.xml</param-value>
</context-param>
<!-- 配置Spring的监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 解析乱码 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置SpringMVC后台 .do -->
<servlet>
<servlet-name>back</servlet-name>
<servlet-class>org.springframework.web.servlet.dispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>back</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 启用注解 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 配置SpringMVC -->
<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
<context:component-scan base-package="com.cungudafa.spingmvc01" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 上传文件的处理器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
<!-- JSP视图 -->
<!-- 定义跳转的文件的前后缀 ,视图模式配置-->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- controller中return时会自动加上前缀和后缀,变成一个完整的url -->
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
package com.cungudafa.spingmvc01.controller;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.cungudafa.spingmvc01.bean.UserInfo;
@Controller
@RequestMapping("/")
public class UserInfoController {
@RequestMapping(value="index")
public String userIndex(String userName,String userPassword){//直接同命名
System.out.println("添加操作的业务逻辑:"+userName+" "+userPassword);
return "success";
}
@RequestMapping("login")
public String login(){
return "login";
}
@RequestMapping(value="dologin")
public String login(UserInfo a,HttpSession session){//UserInfo a 封装对象,实例化;HttpSession session传值
System.out.println("用户:"+a.getUserName()+"\t密码:"+a.getUserPassword());
session.setAttribute("user", a);//从后台controller再传回前端页面,可调用user打印出来
return "success";
}
}
package com.cungudafa.spingmvc01.controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.cungudafa.spingmvc01.bean.UserInfo;
/*
* 一个控制器
* @author Administrator
*
*/
@Controller
@RequestMapping("/")
public class UserInfoController {
@RequestMapping(value="index")
public String userIndex(String userName,String userPassword){
System.out.println("添加操作的业务逻辑:"+userName+" "+userPassword);
return "success";
}
@RequestMapping("login")
public String login(){
return "login";
}
@RequestMapping(value="dologin")
public String login(UserInfo a,HttpSession session){
System.out.println("用户:"+a.getUserName()+"\t密码:"+a.getUserPassword());
session.setAttribute("user", a);
return "success";
}
@RequestMapping("index1")
public void index1(HttpServletResponse response){
try {
response.sendRedirect("/SpingMVC01/index.jsp");
} catch (IOException e) {
// Todo Auto-generated catch block
e.printstacktrace();
}
}
@RequestMapping("index2")
public void index2(HttpServletResponse response){
try {
PrintWriter out = response.getWriter();
out.println("hello");
} catch (IOException e) {
// Todo Auto-generated catch block
e.printstacktrace();
}
}
@RequestMapping("index301")
public String index301(){
return "login";
}
@RequestMapping("index302")
public @ResponseBody String index302(){
return "login";
}
@RequestMapping("student/{id}")
public String find(@PathVariable("id") Integer id,HttpSession session){
System.out.println("id = " + id);
session.setAttribute("id", id);
return "index";
}
}