/// <summary>
         /// 执行动作:耗时而已
         /// </summary>
         private void TestThread(string threadName)
         {
             Console.WriteLine("TestThread Start  Name={2}当前线程的id:{0},当前时间为{1},",
                 System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"), threadName);
             ;
             ; i < ; i++)
             {
                 sum += i;
             }
             //Thread.Sleep(1000);
             Console.WriteLine("TestThread End  Name={2}当前线程的id:{0},当前时间为{1},计算结果{3}",
                 System.Threading.Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"), threadName, sum);
         }

TestThread

同步方法

         private void btnSync_Click(object sender, EventArgs e)
         {
             Stopwatch watch = new Stopwatch();
             watch.Start();

             Console.WriteLine();
             Console.WriteLine("*********************************btnSync_Click Start*********************************************");
             Console.WriteLine("btnSync_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);

             ; i < ; i++)
             {
                 string name = string.Format("btnSync_Click_{0}", i);
                 TestThread(name);
             }
             watch.Stop();
             Console.WriteLine("*********************************btnSync_Click End {0}********************************************", watch.ElapsedMilliseconds);
             Console.WriteLine();

         }    

异步调用

 异步调用
  同步方法会卡界面,异步多线程不会,原因:同步方法占用了UI线程,无法响应其他操作;异步多线程,UI线程不需要等待计算,计算由子线程完成
  同步方法慢,只有主线程计算;异步方法快,启动了多个线程同时计算,会占用更多的资源(多线程的调度管理,也是需要消耗资源的)
  异步方法的启动和执行时无序,原因:线程的申请是无序获取;不同线程同一个任务的执行速度也不一定相同;
 1        Stopwatch watch = new Stopwatch();
             watch.Start();

             Console.WriteLine();
             Console.WriteLine("*********************************btnAsync_Click Start*********************************************");
             Console.WriteLine("btnAsync_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);

             List<IAsyncResult> asyncResultList = new List<IAsyncResult>();

             ; i < ; i++)
             {
                 string name = string.Format("btnSync_Click_{0}", i);
                 Action<string> act = TestThread;
                 //act.Invoke(name);
                 asyncResultList.Add(act.BeginInvoke(name, null, null));
                 //Thread.Sleep(1);
             }
           watch.Stop();

             Console.WriteLine("*********************************btnAsync_Click End {0}********************************************", watch.ElapsedMilliseconds);
             Console.WriteLine();    

等待:

             foreach (var item in asyncResultList)
             {
                 item.AsyncWaitHandle.WaitOne();
             }
 或者
             )
             {
                 Thread.Sleep();//主线程等待着
             }

共有资源的访问

;
private static object IntValueLock = new object();
        ; i < ; i++)
             {
                 IntValue++;
             }

             Action act = () =>
                 {
                     lock (IntValueLock)
                     {
                         IntValue++;
                         Console.WriteLine(IntValue.ToString());
                     }
                 };
             ; i < ; i++)
             {
                 act.BeginInvoke(null, null);
             }

多线程 Thread

        Stopwatch watch = new Stopwatch();
             watch.Start();

             Console.WriteLine();
             Console.WriteLine("*********************************btnThreads_Click Start*********************************************");
             Console.WriteLine("btnThreads_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);

             //表示在 System.Threading.Thread 上执行的方法。  包含该线程过程的数据的对象。
             ParameterizedThreadStart method = t => TestThread(t.ToString());
             List<Thread> threadList = new List<Thread>();
             ; i < ; i++)
             {
                 string name = string.Format("btnSync_Click_{0}", i);
                 Thread thread = new Thread(method);//默认是前台线程,进程取消后,还会完成计算任务
                 //thread.IsBackground = true;//设置成后台线程,进程取消后,立即结束
                 thread.Start(name);
                 threadList.Add(thread);
             }
             )
             {
                 Thread.Sleep();//主线程等待
                 Console.WriteLine("btnThreads_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);
             }

             //foreach (var thread in threadList)
             //{
             //    thread.Join();//阻塞调用线程,直到某个线程终止为止。
             //}

             watch.Stop();
             Console.WriteLine("*********************************btnThreads_Click End {0}********************************************", watch.ElapsedMilliseconds);
             Console.WriteLine();

对比委托的beginInvoke的回调,Thread怎么有回调呢?而且IAsyncResult可以获取其结果

     // 摘要:
     //     表示异步操作的状态。
     [ComVisible(true)]
     public interface IAsyncResult
     {
         // 摘要:
         //     获取用户定义的对象,它限定或包含关于异步操作的信息。
         //
         // 返回结果:
         //     用户定义的对象,它限定或包含关于异步操作的信息。
         object AsyncState { get; }
         //
         // 摘要:
         //     获取用于等待异步操作完成的 System.Threading.WaitHandle。
         //
         // 返回结果:
         //     用于等待异步操作完成的 System.Threading.WaitHandle。
         WaitHandle AsyncWaitHandle { get; }
         //
         // 摘要:
         //     获取一个值,该值指示异步操作是否同步完成。
         //
         // 返回结果:
         //     如果异步操作同步完成,则为 true;否则为 false。
         bool CompletedSynchronously { get; }
         //
         // 摘要:
         //     获取一个值,该值指示异步操作是否已完成。
         //
         // 返回结果:
         //     如果操作完成则为 true,否则为 false。
         bool IsCompleted { get; }

IAsyncResult

不带返回值

        /// <summary>
         /// 带回掉和返回值的线程写法
         /// </summary>
         /// <param name="func">执行方法-带参数</param>
         /// <param name="callback">回调</param>
         /// <returns></returns>
         private string ThreadWithCallback(Func<string> func, Action callback)
         {
             string result = null;

             ThreadStart method = new ThreadStart(
                () =>
                {
                    result = func();
                    callback();
                });

             Thread thread = new Thread(method);
             thread.Start();

             thread.Join();//等待线程完成
             return result;
         }

带返回值

         /// <summary>
         /// 带回掉和返回值的线程写法
         /// </summary>
         /// <param name="func">执行方法-带参数</param>
         /// <param name="callback">回调</param>
         /// <returns></returns>
         private string ThreadWithCallback(Func<string> func, Action callback)
         {
             string result = null;

             ThreadStart method = new ThreadStart(
                () =>
                {
                    result = func();
                    callback();
                });

             Thread thread = new Thread(method);
             thread.Start();

             thread.Join();//等待线程完成
             return result;
         }

线程池ThreadPool

         Stopwatch watch = new Stopwatch();
             watch.Start();

             Console.WriteLine();
             Console.WriteLine("*********************************btnThreadPool_Click Start*********************************************");
             Console.WriteLine("btnThreadPool_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);
             ; i < ; i++)
             {
                 string name = string.Format("btnThreadPool_Click{0}", i);
                 //表示线程池线程要执行的方法
                 WaitCallback act = t => TestThread(t.ToString());
                 //将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。
                 //System.Threading.WaitCallback,它表示要执行的方法。
                 ThreadPool.QueueUserWorkItem(act, name);
             }

             watch.Stop();
             Console.WriteLine("*********************************btnThreadPool_Click End {0}********************************************", watch.ElapsedMilliseconds);
             Console.WriteLine();

可以设置数目,这是Thread没有的

        ThreadPool.SetMaxThreads(, );//最小也是核数
             ThreadPool.SetMinThreads(, );
             int workerThreads;
             int ioThreads;
             //-----------------------工作线程        和       IO线程
             ThreadPool.GetMaxThreads(out workerThreads, out ioThreads);
             Console.WriteLine(String.Format("Max worker threads: {0};    Max I/O threads: {1}", workerThreads, ioThreads));

             ThreadPool.GetMinThreads(out workerThreads, out ioThreads);
             Console.WriteLine(String.Format("Min worker threads: {0};    Min I/O threads: {1}", workerThreads, ioThreads));

             ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads);
             Console.WriteLine(String.Format("Available worker threads: {0};    Available I/O threads: {1}", workerThreads, ioThreads));

信号量--线程安全

    // 摘要:
     //     通知一个或多个正在等待的线程已发生事件。 此类不能被继承。
     [ComVisible(true)]
     public sealed class ManualResetEvent : EventWaitHandle
     {
         // 摘要:
         //     用一个指示是否将初始状态设置为终止的布尔值初始化 System.Threading.ManualResetEvent 类的新实例。
         //
         // 参数:
         //   initialState:
         //     如果为 true,则将初始状态设置为终止;如果为 false,则将初始状态设置为非终止。
         public ManualResetEvent(bool initialState);
     }

ManualResetEvent

            //如果为 true,则将初始状态设置为终止;如果为 false,则将初始状态设置为非终止
             ManualResetEvent test = new ManualResetEvent(false);

             new Action(() =>
             {
                 Thread.Sleep();
                 test.Set();
             }).BeginInvoke(null, null);

             test.WaitOne();//是无法通过的----非终止状态--线程阻止了就一直等

             test.Set();//变成true-----将事件状态设置为终止状态,允许一个或多个等待线程继续。
             test.WaitOne();//立即通过的---终止状态---线程阻止结束就继续执行

             test.Reset();//重置为false---将事件状态设置为非终止状态,导致线程阻止
             test.WaitOne();//是无法通过的

线程--信号量等待

         ManualResetEvent test = new ManualResetEvent(false);
             WaitCallback act = t =>
                 {
                     TestThread(t.ToString());
                     test.Set();//完成一个才为true
                 };
             ThreadPool.QueueUserWorkItem(act, "btnThreadPool_Click");
             test.WaitOne();

总结:

Thread回收比较慢,ThreadPool回收快,效果要好点。

异步是基于线程池的,但是回收的加上EndInvoke(),不然回收会比较慢.

Task and TaskFactory

         private void btnTask_Click(object sender, EventArgs e)
         {
             Stopwatch watch = new Stopwatch();
             watch.Start();

             Console.WriteLine();
             Console.WriteLine("*********************************btnTask_Click Start*********************************************");
             Console.WriteLine("btnTask_Click当前主线程的id:{0}", Thread.CurrentThread.ManagedThreadId);

             TaskFactory taskFactory = new TaskFactory();
             List<Task> taskList = new List<Task>();
             ; i < ; i++)
             {
                 string name = string.Format("btnTask_Click{0}", i);
                 Action<object> act = t => TestThread(t.ToString());
                 Task task = taskFactory.StartNew(act, name);

                 taskList.Add(task);
             }
             taskFactory.ContinueWhenAny(taskList.ToArray(), t =>
             {
                 Console.WriteLine("taskFactory.ContinueWhenAny {0}", Thread.CurrentThread.ManagedThreadId);
                 Console.WriteLine(t.AsyncState);
                 Console.WriteLine(t.IsCompleted);
             });//这是回调,会等到某个Task完成后执行,不卡当前线程
             taskFactory.ContinueWhenAll(taskList.ToArray(), taskArray =>
                 {
                     Console.WriteLine("taskFactory.ContinueWhenAll {0}", Thread.CurrentThread.ManagedThreadId);
                     foreach (var item in taskArray)
                     {
                         Console.WriteLine(item.AsyncState);
                         Console.WriteLine(item.IsCompleted);
                     }
                 });//这是回调,会等到全部Task完成后执行,不卡当前线程

             //Task.WaitAny(taskList.ToArray());//所在的线程等待   目前在主线程   会等待某个Task的完成
             //Console.WriteLine("某个Task都执行完毕了!");
             //Task.WaitAll(taskList.ToArray());//所在的线程等待   目前在主线程   会等待全部Task的完成
             //Console.WriteLine("所有的Task都执行完毕了!");
             watch.Stop();
             Console.WriteLine("*********************************btnTask_Click End {0}********************************************", watch.ElapsedMilliseconds);
             Console.WriteLine();
         }

Parallel

         //
         // 摘要:
         //     尽可能并行执行提供的每个操作。
         //
         // 参数:
         //   actions:
         //     要执行的 System.Action 数组。
         //
         // 异常:
         //   System.ArgumentNullException:
         //     actions 参数为 null。
         //
         //   System.AggregateException:
         //     当 actions 数组中的任何操作引发异常时引发的异常。
         //
         //   System.ArgumentException:
         //     actions数组包含 null 个元素。
         public static void Invoke(params Action[] actions);
         //
         // 摘要:
         //     执行所提供的每个操作,而且尽可能并行运行,除非用户取消了操作。
         //
         // 参数:
         //   parallelOptions:
         //     一个对象,用于配置此操作的行为。
         //
         //   actions:
         //     要执行的操作数组。
         //
         // 异常:
         //   System.OperationCanceledException:
         //     设置处于 parallelOptions 中的 System.Threading.CancellationToken。
         //
         //   System.ArgumentNullException:
         //     actions 参数为 null。-或- 方parallelOptions 参数为 null。
         //
         //   System.AggregateException:
         //     当 actions 数组中的任何操作引发异常时引发的异常。
         //
         //   System.ArgumentException:
         //     actions 数组包含 null 元素。
         //
         //   System.ObjectDisposedException:
         //     在 parallelOptions 中与 System.Threading.CancellationToken关联的 System.Threading.CancellationTokenSource
         //     已被释放。
         public static void Invoke(ParallelOptions parallelOptions, params Action[] actions);

public static class Parallel

             //就是在Task的基础上封装,多个任务并行计算,其实就是Task + WaitAll,而且主线程也在计算
             Parallel.Invoke(() => Console.WriteLine("1 当前线程id={0}", Thread.CurrentThread.ManagedThreadId)
                 , () => Console.WriteLine("2 当前线程id={0}", Thread.CurrentThread.ManagedThreadId)
                 , () => Console.WriteLine("3 当前线程id={0}", Thread.CurrentThread.ManagedThreadId)
                 , () => Console.WriteLine("4 当前线程id={0}", Thread.CurrentThread.ManagedThreadId));
             //计算全部完成后,才会进入下一行代码,看上去就是同步编程

Parallel.ForEach/For

             Parallel.ForEach<, , , ,  },
                    t =>
                    {
                        Console.WriteLine("{0} ForEach当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
                        Thread.Sleep();
                    });

             Parallel.For(, , t =>
                 {
                     Console.WriteLine("{0} For当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
                     Thread.Sleep();
                 });

可设置最大并行数

 namespace System.Threading.Tasks
 {
     // 摘要:
     //     存储用于配置 System.Threading.Tasks.Parallel 类的方法的操作的选项。
     public class ParallelOptions
     {
         // 摘要:
         //     初始化 System.Threading.Tasks.ParallelOptions 类的新实例。
         public ParallelOptions();

         // 摘要:
         //     获取或设置与此 System.Threading.Tasks.ParallelOptions 实例关联的 System.Threading.CancellationToken。
         //
         // 返回结果:
         //     与此实例关联的标记。
         public CancellationToken CancellationToken { get; set; }
         //
         // 摘要:
         //     获取或设置此 ParallelOptions 实例所允许的最大并行度。
         //
         // 返回结果:
         //     一个表示最大并行度的整数。
         //
         // 异常:
         //   System.ArgumentOutOfRangeException:
         //     当此 System.Threading.Tasks.ParallelOptions.MaxDegreeOfParallelism 设置为 0 或小于
         //     -1 的某个值时引发的异常。
         public int MaxDegreeOfParallelism { get; set; }
         //
         // 摘要:
         //     获取或设置与此 System.Threading.Tasks.ParallelOptions 实例关联的 System.Threading.Tasks.TaskScheduler。
         //     将此属性设置为 null,以指示应使用当前计划程序。
         //
         // 返回结果:
         //     与此实例关联的任务计划程序。
         public TaskScheduler TaskScheduler { get; set; }
     }
 }

MaxDegreeOfParallelism

             ParallelOptions options = new ParallelOptions()
             {
                 MaxDegreeOfParallelism =
             };

             Parallel.For(, , options, t =>
             {
                 Console.WriteLine("{0} For当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
                 Thread.Sleep();
             });

ParallelLoopState

         //
         // 摘要:
         //     执行 for(在 Visual Basic 中为 For)循环,其中可能会并行运行迭代,而且可以配置循环选项,可以监视和操作循环的状态。
         //
         // 参数:
         //   fromInclusive:
         //     开始索引(含)。
         //
         //   toExclusive:
         //     结束索引(不含)。
         //
         //   parallelOptions:
         //     一个对象,用于配置此操作的行为。
         //
         //   body:
         //     将为每个迭代调用一次的委托。
         //
         // 返回结果:
         //     包含有关已完成的循环部分的信息的结构。
         //
         // 异常:
         //   System.OperationCanceledException:
         //     取消 parallelOptions 参数中的 System.Threading.CancellationToken。
         //
         //   System.ArgumentNullException:
         //     body 参数为 null。-或- 方parallelOptions 参数为 null。
         //
         //   System.AggregateException:
         //     包含在所有线程上引发的全部单个异常的异常。
         //
         //   System.ObjectDisposedException:
         //     在 parallelOptions 中与 System.Threading.CancellationToken关联的 System.Threading.CancellationTokenSource
         //     已被释放。
         public static ParallelLoopResult For(int fromInclusive, int toExclusive, ParallelOptions parallelOptions, Action<int, ParallelLoopState> body);

ParallelLoopState

state.Break()          + return;
或者 state.Stop()
             ParallelOptions options = new ParallelOptions()
             {
                 MaxDegreeOfParallelism =
             };

             //Parallel.For(0, 100, options, t =>
             //{
             //    Console.WriteLine("{0} For当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
             //    Thread.Sleep(3000);
             //});

             Parallel.For(, , options, (t, state) =>
             {
                 Console.WriteLine("{0} For当前线程id={1}", t, Thread.CurrentThread.ManagedThreadId);
                 state.Break();//循环结束
                 //state.Stop();//paraller结束计算
                 return;//带上return才有效
                 //二者不能同时出现,会异常
                 Thread.Sleep();
             });

多线程的临时变量

             Action<int> act = i =>
                 {
                     Thread.Sleep();
                     Console.WriteLine(i);
                 };
             ; i < ; i++)
             {
                 Task.Run(() => act(i));//多线程任务真的执行时,i=10了
                 //或者
                 //new Action(() => act(i)).BeginInvoke(null, null);
             }

解决办法:

              Action<int> act = i =>
                 {
                     Thread.Sleep();
                     Console.WriteLine(i);
                 };
             ; i < ; i++)
             {
                 int k = i;//每次循环,声明一个新的变量k
                 Task.Run(() => act(k));
             }

多线程的异常处理

                 TaskFactory taskFactory = new TaskFactory();
                 List<Task> taskList = new List<Task>();
                 //     通知 System.Threading.CancellationToken,告知其应被取消。
                 CancellationTokenSource cts = new CancellationTokenSource();
                 ; i < ; i++)
                 {
                     string name = string.Format("btnTask_Click{0}", i);
                     Action<object> act = t =>
                         {
                             try
                             {
                                 if (t.ToString().Equals("btnTask_Click2"))
                                 {
                                     throw new Exception(string.Format("{0} 执行失败", t));
                                 }
                                 if (t.ToString().Equals("btnTask_Click3"))
                                 {
                                     throw new Exception(string.Format("{0} 执行失败", t));
                                 }
                                 Thread.Sleep();
                                 //     获取是否已请求取消此 System.Threading.CancellationTokenSource。
                                 if (!cts.IsCancellationRequested)//IsCancellationRequested 被取消
                                 {
                                     Console.WriteLine("{0} 执行成功", t);
                                 }
                                 else
                                 {
                                     Console.WriteLine("{0} 被取消", t);
                                 }
                             }
                             catch (Exception ex)
                             {
                                 //     传达取消请求。
                                 cts.Cancel();
                                 Console.WriteLine("子线程异常 {0}", ex.Message);
                             }
                         };
                     Task task = taskFactory.StartNew(act, name, cts.Token);
                     taskList.Add(task);
                 }
                 Task.WaitAll(taskList.ToArray());
              ; i < ; i++)
             {
                 string name = string.Format("btnSync_Click_{0}", i);
                 Action<string> act = TestThread;
                 //act.Invoke(name);
                 asyncResultList.Add(act.BeginInvoke(name, null, null));
                 //Thread.Sleep(1);
             }
             //EndInvoke()    

EndInvoke

using System.Threading;的更多相关文章

  1. .Net多线程编程—System.Threading.Tasks.Parallel

    System.Threading.Tasks.Parallel类提供了Parallel.Invoke,Parallel.For,Parallel.ForEach这三个静态方法. 1 Parallel. ...

  2. System.Threading.Timer 定时器的用法

    System.Threading.Timer 是C# 中的一个定时器,可以定时(不断循环)执行一个任务.它是在线程上执行的,具有很好的安全性.为此  .Net Framework 提供了5个重载的构造 ...

  3. C# System.Threading.Timer 使用方法

    public class TimerHelper { System.Threading.Timer timer; public TaskSendMMS tasksendmms { get; set; ...

  4. C#中的线程四(System.Threading.Thread)

    C#中的线程四(System.Threading.Thread) 1.最简单的多线程调用 System.Threading.Thread类构造方法接受一个ThreadStart委托,改委托不带参数,无 ...

  5. C#错误之 System.Threading.ThreadAbortException:正在中止线程

    参考:http://www.cnblogs.com/chendaoyin/archive/2013/06/27/3159211.html 1.开启一个子线程 //开启一个子线程,子线程调用方法 Met ...

  6. System.Threading.Timer使用心得

    System.Threading.Timer 是一个使用回调方法的计时器,而且由线程池线程服务,简单且对资源要求不高. "只要在使用 Timer,就必须保留对它的引用."对于任何托 ...

  7. “System.Threading.ThreadAbortException”类型的第一次机会异常在 mscorlib.dll 中发

    问题原因: Thread.Abort 方法 .NET Framework 4  其他版本   1(共 1)对本文的评价是有帮助 - 评价此主题 在调用此方法的线程上引发 ThreadAbortExce ...

  8. System.Threading.ThreadAbortException: 正在中止线程。

    在 System.Threading.ThreadAbortException 中第一次偶然出现的"mscorlib.dll"类型的异常 "System.Threadin ...

  9. 找不到方法"Boolean System.Threading.WaitHandle.WaitOne(TimeSpan)"的解决方案

    找不到方法"Boolean System.Threading.WaitHandle.WaitOne(TimeSpan)" http://www.microsoft.com/down ...

  10. using System.Threading.Tasks;

    using System.Threading.Tasks; .Net并行库介绍——Task1

随机推荐

  1. extjs grid renderer用法【转载】

    今天在做项目时,需要在列表中的某列添加一个超链接,首先要取得当前选中行的数据,判断数据类型,然后链接到不同的页面,研究下.发现ExtJs提供了一个很强的方法如下: var cm = new Ext.g ...

  2. POJ 2420 A Star not a Tree? 爬山算法

    B - A Star not a Tree? Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/co ...

  3. codeforces 468B 2-sat

    今天明确了2-SAT; 表示对一对整数之间的关系是否存在 #include<cstdio> #include<algorithm> #include<iostream&g ...

  4. Java 中队列的使用

    刚才看见群里的一个朋友在问队列的使用,确实在现实的写代码中非常少使用队列的,反正我是从来没使用过.仅仅是学数据结构的时候学过. 以下是我写的一个小样例,希望有不足之处请提出改正.O(∩_∩)O~ 看代 ...

  5. android圆角View实现及不同版本这间的兼容(android3.0过后的版本)

    http://blog.csdn.net/lovecluo/article/details/8710174 在做我们自己的APP的时候,为了让APP看起来更加的好看,我们就需要将我们的自己的View做 ...

  6. [安卓学习]AndroidManifest.xml文件内容详解

    一,重要性 AndroidManifest.xml是Android应用程序中最重要的文件之一.它是Android程序的全局配置文件,是每个 android程序中必须的文件.它位于我们开发的应用程序的根 ...

  7. SSH框架之Struts(2)——Struts的执行流程之配置文件

    上篇我们大致了解了一下採用了Struts框架的web页面运行流程. 接下来的几篇我们通过Struts的源代码来学习一下Struts的内部原理. 当server启动的时候.server会依据配置文件初始 ...

  8. /proc/sys/net/ipv4/下各项的意义

        /proc/sys/net/ipv4/icmp_timeexceed_rate这个在traceroute时导致著名的“Solaris middle star”.这个文件控制发送ICMP Tim ...

  9. Oracle_集合

    游标遍历select语句 set serveroutput on; declare type sp_test1_cursor is ref cursor; test1_cursor sp_test1_ ...

  10. java_线程安全-service

    package com.demo.test; import java.util.Collections; import java.util.HashMap; import java.util.Map; ...