当前位置: 首页 > 编程日记 > 正文

java.util.concurrent包API学习笔记

newFixedThreadPool
创建一个固定大小的线程池。
shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭。
awaitTermination():用于等待子线程结束,再继续执行下面的代码。该例中我设置一直等着子线程结束。Java代码  收藏代码
public class Test {  public static void main(String[] args) throws IOException, InterruptedException {  ExecutorService service = Executors.newFixedThreadPool(2);  for (int i = 0; i < 4; i++) {  Runnable run = new Runnable() {  @Override  public void run() {  System.out.println("thread start");  }  };  service.execute(run);  }  service.shutdown();  service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);  System.out.println("all thread complete");  }  
}  输出:
thread start
thread start
thread start
thread start
all thread complete
newScheduledThreadPool
这个先不说,我喜欢用spring quartz.
CyclicBarrier
假设有只有的一个场景:每个线程代表一个跑步运动员,当运动员都准备好后,才一起出发,只要有一个人没有准备好,大家都等待.Java代码  收藏代码
import java.io.IOException;  
import java.util.Random;  
import java.util.concurrent.BrokenBarrierException;  
import java.util.concurrent.CyclicBarrier;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  class Runner implements Runnable {  private CyclicBarrier barrier;  private String name;  public Runner(CyclicBarrier barrier, String name) {  super();  this.barrier = barrier;  this.name = name;  }  @Override  public void run() {  try {  Thread.sleep(1000 * (new Random()).nextInt(8));  System.out.println(name + " 准备OK.");  barrier.await();  } catch (InterruptedException e) {  e.printStackTrace();  } catch (BrokenBarrierException e) {  e.printStackTrace();  }  System.out.println(name + " Go!!");  }  
}  public class Race {  public static void main(String[] args) throws IOException, InterruptedException {  CyclicBarrier barrier = new CyclicBarrier(3);  ExecutorService executor = Executors.newFixedThreadPool(3);  executor.submit(new Thread(new Runner(barrier, "zhangsan")));  executor.submit(new Thread(new Runner(barrier, "lisi")));  executor.submit(new Thread(new Runner(barrier, "wangwu")));  executor.shutdown();  }  }  输出:
wangwu 准备OK.
zhangsan 准备OK.
lisi 准备OK.
lisi Go!!
zhangsan Go!!
wangwu Go!!
ThreadPoolExecutornewFixedThreadPool生成一个固定的线程池,顾名思义,线程池的线程是不会释放的,即使它是Idle。这就会产生性能问题,比如如果线程池的大小为200,当全部使用完毕后,所有的线程会继续留在池中,相应的内存和线程切换(while(true)+sleep循环)都会增加。如果要避免这个问题,就必须直接使用ThreadPoolExecutor()来构造。可以像Tomcat的线程池一样设置“最大线程数”、“最小线程数”和“空闲线程keepAlive的时间”。ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)  corePoolSize:池中所保存的线程数,包括空闲线程(非最大同时干活的线程数)。如果池中线程数多于 corePoolSize,则这些多出的线程在空闲时间超过 keepAliveTime 时将会终止。
maximumPoolSize:线程池中最大线程数
keepAliveTime:线程空闲回收的时间
unit:keepAliveTime的单位
workQueue:保存任务的队列,可以如下选择:无界队列: new LinkedBlockingQueue<Runnable>();有界队列: new ArrayBlockingQueue<Runnable>(8);你不想让客户端无限的请求吃光你的CPU和内存吧,那就用有界队列
handler:当提交任务数大于队列size会抛出RejectedExecutionException,可选的值为:ThreadPoolExecutor.CallerRunsPolicy 等待队列空闲
ThreadPoolExecutor.DiscardPolicy:丢弃要插入队列的任务
ThreadPoolExecutor.DiscardOldestPolicy:删除队头的任务
关于corePoolSize和maximumPoolSize:Java官方Docs写道:
当新任务在方法 execute(java.lang.Runnable) 中提交时,如果运行的线程少于 corePoolSize,则创建新线程来处理请求(即使存在空闲线程)。如果运行的线程多于 corePoolSize 而少于 maximumPoolSize,则仅当队列(queue)满时才创建新线程。如果设置的 corePoolSize 和 maximumPoolSize 相同,则创建了固定大小的线程池。如果将 maximumPoolSize 设置为基本的无界值(如 Integer.MAX_VALUE),则允许池适应任意数量的并发任务。Java代码  收藏代码
public class Test {  public static void main(String[] args) {  BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();  ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.DAYS, queue);  for (int i = 0; i < 20; i++) {  final int index = i;  executor.execute(new Runnable() {  public void run() {  try {  Thread.sleep(4000);  } catch (InterruptedException e) {  e.printStackTrace();  }  System.out.println(String.format("thread %d finished", index));  }  });  }  executor.shutdown();  }  
}  原子变量(Atomic )
并发库中的BlockingQueue是一个比较好玩的类,顾名思义,就是阻塞队列。该类主要提供了两个方法put()和take(),前者将一个对象放到队列中,如果队列已经满了,就等待直到有空闲节点;后者从head取一个对象,如果没有对象,就等待直到有可取的对象。下面的例子比较简单,一个读线程,用于将要处理的文件对象添加到阻塞队列中,另外四个写线程用于取出文件对象,为了模拟写操作耗时长的特点,特让线程睡眠一段随机长度的时间。另外,该Demo也使用到了线程池和原子整型(AtomicInteger),AtomicInteger可以在并发情况下达到原子化更新,避免使用了synchronized,而且性能非常高。由于阻塞队列的put和take操作会阻塞,为了使线程退出,在队列中添加了一个“标识”,算法中也叫“哨兵”,当发现这个哨兵后,写线程就退出。Java代码  收藏代码
import java.io.File;  
import java.io.FileFilter;  
import java.util.concurrent.BlockingQueue;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.LinkedBlockingQueue;  
import java.util.concurrent.atomic.AtomicInteger;  public class Test {  static long randomTime() {  return (long) (Math.random() * 1000);  }  public static void main(String[] args) {  // 能容纳100个文件  final BlockingQueue<File> queue = new LinkedBlockingQueue<File>(100);  // 线程池  final ExecutorService exec = Executors.newFixedThreadPool(5);  final File root = new File("D:\\dist\\blank");  // 完成标志  final File exitFile = new File("");  // 读个数  final AtomicInteger rc = new AtomicInteger();  // 写个数  final AtomicInteger wc = new AtomicInteger();  // 读线程  Runnable read = new Runnable() {  public void run() {  scanFile(root);  scanFile(exitFile);  }  public void scanFile(File file) {  if (file.isDirectory()) {  File[] files = file.listFiles(new FileFilter() {  public boolean accept(File pathname) {  return pathname.isDirectory() || pathname.getPath().endsWith(".log");  }  });  for (File one : files)  scanFile(one);  } else {  try {  int index = rc.incrementAndGet();  System.out.println("Read0: " + index + " " + file.getPath());  queue.put(file);  } catch (InterruptedException e) {  }  }  }  };  exec.submit(read);  // 四个写线程  for (int index = 0; index < 4; index++) {  // write thread  final int num = index;  Runnable write = new Runnable() {  String threadName = "Write" + num;  public void run() {  while (true) {  try {  Thread.sleep(randomTime());  int index = wc.incrementAndGet();  File file = queue.take();  // 队列已经无对象  if (file == exitFile) {  // 再次添加"标志",以让其他线程正常退出  queue.put(exitFile);  break;  }  System.out.println(threadName + ": " + index + " " + file.getPath());  } catch (InterruptedException e) {  }  }  }  };  exec.submit(write);  }  exec.shutdown();  }  }  CountDownLatch从名字可以看出,CountDownLatch是一个倒数计数的锁,当倒数到0时触发事件,也就是开锁,其他人就可以进入了。在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。 
CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。
一个CountDouwnLatch实例是不能重复使用的,也就是说它是一次性的,锁一经被打开就不能再关闭使用了,如果想重复使用,请考虑使用CyclicBarrier。
下面的例子简单的说明了CountDownLatch的使用方法,模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。Java代码  收藏代码
import java.util.concurrent.CountDownLatch;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  public class Test {  public static void main(String[] args) throws InterruptedException {  // 开始的倒数锁  final CountDownLatch begin = new CountDownLatch(1);  // 结束的倒数锁  final CountDownLatch end = new CountDownLatch(10);  // 十名选手  final ExecutorService exec = Executors.newFixedThreadPool(10);  for (int index = 0; index < 10; index++) {  final int NO = index + 1;  Runnable run = new Runnable() {  public void run() {  try {  begin.await();  Thread.sleep((long) (Math.random() * 10000));  System.out.println("No." + NO + " arrived");  } catch (InterruptedException e) {  } finally {  end.countDown();  }  }  };  exec.submit(run);  }  System.out.println("Game Start");  begin.countDown();  end.await();  System.out.println("Game Over");  exec.shutdown();  }  }  使用Callable和Future实现线程等待和多线程返回值假设在main线程启动一个线程,然后main线程需要等待子线程结束后,再继续下面的操作,我们会通过join方法阻塞main线程,代码如下:Java代码  收藏代码
Runnable runnable = ...;  
Thread t = new Thread(runnable);  
t.start();  
t.join();  
......  通过JDK1.5线程池管理的线程可以使用Callable和Future实现(join()方法无法应用到在线程池线程)Java代码  收藏代码
import java.util.concurrent.Callable;  
import java.util.concurrent.ExecutionException;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  public class Test {  public static void main(String[] args) throws InterruptedException, ExecutionException {  System.out.println("start main thread");  final ExecutorService exec = Executors.newFixedThreadPool(5);  Callable<String> call = new Callable<String>() {  public String call() throws Exception {  System.out.println("  start new thread.");  Thread.sleep(1000 * 5);  System.out.println("  end new thread.");  return "some value.";  }  };  Future<String> task = exec.submit(call);  Thread.sleep(1000 * 2);  task.get(); // 阻塞,并待子线程结束,  exec.shutdown();  exec.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);  System.out.println("end main thread");  }  }  Java代码  收藏代码
import java.util.ArrayList;  
import java.util.List;  
import java.util.concurrent.Callable;  
import java.util.concurrent.ExecutionException;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  /** 
* 多线程返回值测试 
*/  
public class ThreadTest {  public static void main(String[] args) throws InterruptedException, ExecutionException {  System.out.println("start main thread");  int threadCount = 5;  final ExecutorService exec = Executors.newFixedThreadPool(threadCount);  List<Future<Integer>> tasks = new ArrayList<Future<Integer>>();  for (int i = 0; i < threadCount; i++) {  Callable<Integer> call = new Callable<Integer>() {  public Integer call() throws Exception {  Thread.sleep(1000);  return 1;  }  };  tasks.add(exec.submit(call));  }  long total = 0;  for (Future<Integer> future : tasks) {  total += future.get();  }  exec.shutdown();  System.out.println("total: " + total);  System.out.println("end main thread");  }  
}  CompletionService
这个东西的使用上很类似上面的example,不同的是,它会首先取完成任务的线程。下面的参考文章里,专门提到这个,大家有兴趣可以看下,例子:Java代码  收藏代码
import java.util.concurrent.Callable;  
import java.util.concurrent.CompletionService;  
import java.util.concurrent.ExecutionException;  
import java.util.concurrent.ExecutorCompletionService;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Future;  public class Test {  public static void main(String[] args) throws InterruptedException,  ExecutionException {  ExecutorService exec = Executors.newFixedThreadPool(10);  CompletionService<String> serv =  new ExecutorCompletionService<String>(exec);  for (int index = 0; index < 5; index++) {  final int NO = index;  Callable<String> downImg = new Callable<String>() {  public String call() throws Exception {  Thread.sleep((long) (Math.random() * 10000));  return "Downloaded Image " + NO;  }  };  serv.submit(downImg);  }  Thread.sleep(1000 * 2);  System.out.println("Show web content");  for (int index = 0; index < 5; index++) {  Future<String> task = serv.take();  String img = task.get();  System.out.println(img);  }  System.out.println("End");  // 关闭线程池  exec.shutdown();  }  
}  Semaphore信号量拿到信号量的线程可以进入代码,否则就等待。通过acquire()和release()获取和释放访问许可。下面的例子只允许5个线程同时进入执行acquire()和release()之间的代码Java代码  收藏代码
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
import java.util.concurrent.Semaphore;  public class Test {  public static void main(String[] args) {  // 线程池  ExecutorService exec = Executors.newCachedThreadPool();  // 只能5个线程同时访问  final Semaphore semp = new Semaphore(5);  // 模拟20个客户端访问  for (int index = 0; index < 20; index++) {  final int NO = index;  Runnable run = new Runnable() {  public void run() {  try {  // 获取许可  semp.acquire();  System.out.println("Accessing: " + NO);  Thread.sleep((long) (Math.random() * 10000));  // 访问完后,释放  semp.release();  } catch (InterruptedException e) {  }  }  };  exec.execute(run);  }  // 退出线程池  exec.shutdown();  }  }  参考:
jdk1.5中的线程池使用简介
http://www.java3z.com/cwbwebhome/article/article2/2875.html
CAS原理
http://www.blogjava.net/syniii/archive/2010/11/18/338387.html?opt=admin
jdk1.5中java.util.concurrent包编写多线程
http://hi.baidu.com/luotoo/blog/item/b895c3c2d650591e0ef47731.html
ExecutorSerive vs CompletionService
http://www.coderanch.com/t/491704/threads/java/ExecutorSerive-vs-CompletionService-- end -- 

  

转载于:https://www.cnblogs.com/IamThat/p/4341125.html

相关文章:

oracle读书记录

很久没有关注自己怕博客了&#xff0c;差不多有两年了。虽然这两年来一直关注51CTO,每天上班打开电脑或者周末在家开启电脑的时候都会浏览一下&#xff0c;这已经是习惯了&#xff0c;但是把自己的blog给忘了。今天&#xff0c;周末&#xff0c;2013年12月21日&#xff0c;同往…

输入、方法的运用

/ /猜数游戏,编写一个功能,完成猜数游戏,产生一个1~10之间的随机数 //与输入的数对对比,返回结果 猜中和没猜中 import java.util.Scanner; //引入&#xff08;输入&#xff09;的util包Scanner public class HelloWorld { public static void main(String[] args) {System…

Rocksdb 利用recycle_log_file_num 重用wal-log文件

recycle_log_file_num 复用wal文件信息&#xff0c; 优化wal文件的空间分配&#xff0c;减少pagecache中文件元信息的更新开销。 为同事提供了一组rocksdb写优化参数之后有一个疑惑的现象被问到&#xff0c;发现之前的一些代码细节有遗忘情况&#xff0c;同时也发现了这个参数…

Java项目:网上商城系统(java+jsp+servlert+mysql+ajax)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述&#xff08;需求文档PPT&#xff09; 功能&#xff1a; 主页显示热销商品&#xff1b;所有商品展示&#xff0c;可进行商品搜索&#xff1b;点 击商品进入商品详情页&#xff0c;显示库存&…

clock函数返回负值~ (转)

使用clock() 函数来进行计时&#xff0c;时不时的返回一个很大的负数&#xff0c;怎么检查也检查不出错误&#xff0c;现在找出错误原因&#xff0c;给大家分享一下。 来源网页&#xff1a;http://kebe-jea.blogbus.com/logs/33603387.html 跑实验的时候&#xff0c;结果时不时…

c实现面向对象编程(3)

http://blog.csdn.net/kennyrose/article/details/7564105转载于:https://www.cnblogs.com/pengkunfan/p/3486612.html

echarts - 条形图grid设置距离绘图区域的距离

在一些数据量过大的情况下&#xff0c;在一个固定的区域绘图往往需要对图表绘制区域的大小进行动态改变。这时候设置条形图距离绘图区域上下左右的距离可使用如下方式&#xff1a;表示条形图的柱子距离绘图区左边30%&#xff0c;距离右边40%&#xff0c;而距离顶部和底部分别为…

TitanDB 中使用Compaction Filter ,产生了预期之外几十倍的读I/O

Compaction过程中 产生大量读I/O 的背景 项目中因大value 需求&#xff0c;引入了PingCap 参考Wisckey 思想实现的key-value分离存储 titan&#xff0c; 使用过程中因为有用到Rocksdb本身的 CompactionFilter功能&#xff0c;所以就直接用TitanDB的option 传入了compaction fi…

Java项目:前台+后台精品图书管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括&#xff1a; 登录注册&#xff0c;办理借阅。借阅记录&#xff0c;预约借阅&#xff0c;借出未还, 借阅逾期&#xff0c;学生管理&#xff0c;图书管理&#xff0c;书库分类查询搜索…

消除 activity 启动时白屏、黑屏问题

默认情况下 activity 启动的时候先把屏幕刷成白色&#xff0c;再绘制界面&#xff0c;绘制界面或多或少有点延迟&#xff0c;这段时间中你看到的就是白屏&#xff0c;显然影响用户体验&#xff0c;怎么消除呢&#xff1f; 在 Activity theme 设置style 即可 1 <style na…

理解并实施:HSRP(CCNA200-120新增考点)

理解并实施:HSRP思科热备路由器协议HSRP&#xff08;HotStandby Router Protocol&#xff09;是企业级网络路由器的故障冗余服务。如图9.116所示&#xff0c;192.168.2.0/24的子网需要与目标192.168.5.2的计算机通信。192.168.2.0/24的子网有两台出口路由器&#xff0c;一台是R…

使用机智云APP控制战舰V3 (转)

源&#xff1a;使用机智云APP控制战舰V3 转载于:https://www.cnblogs.com/LittleTiger/p/10725586.html

从JoinBatchGroup 代码细节 来看Rocksdb的相比于leveldb的写入优势

文章目录1. Rocksdb写入模型2. LevelDB写入的优化点3. Rocksdb 的优化1. Busy Loop2. Short Wait -- SOMETIMES busy Loop3. Long-wait4. 测试验证4. 总结1. Rocksdb写入模型 本节讨论一下Rocksdb在写入链路上的一个优化点&#xff0c;这个优化细节可以说将Rocksdb这个存储引擎…

Java项目:嘟嘟网上商城系统(java+jdbc+jsp+mysql+ajax)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能&#xff1a; 商品的分类展示&#xff0c;用户的注册登录&#xff0c;购物车&#xff0c;订单结算&#xff0c; 购物车加减&#xff0c;后台商品管理&#xff0c;分类管理&#xff0c;订单…

SOAPUI请求及mockservice 使用

1、新建soap Project&#xff0c;输入wsdl的地址&#xff0c;运行request 2.邮件Project&#xff0c;建立mockservice&#xff0c;建立多个response&#xff0c;选在mock operation&#xff0c;选择response dispa…

空间直角坐标系与球面坐标互转

空间直角坐标系与球面坐标互转 1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Text;5 6 namespace AppSurveryTools.SphericalAndCartesian7 {8 class CartesianCoord9 { 10 public double x; 11 public dou…

Ajax 的优势和不足

Ajax 的优势 1. 不需要插件支持 Ajax 不需要任何浏览器插件&#xff0c;就可以被绝大多数主流浏览器所支持&#xff0c;用户只需要允许 JavaScript 在浏览器上执行即可。 2. 优秀的用户体验 这是 Ajax 技术的最大优点&#xff0c;能在不刷新整个页面的前提下更新数据&#xff0…

BitCask 持久化hash存储引擎 原理介绍

文章目录前言引擎背景引擎原理1. 磁盘数据结构2. 内存数据结构3. 读流程4. 数据合并总结前言 最近工作中部分项目中&#xff0c;对存储引擎的需求希望高性能的写、点查&#xff0c;并不需要Range。这里看到大家总会提到BitCask这个存储引擎方案&#xff0c;并不是很了解&#…

C# Socket系列三 socket通信的封包和拆包

通过系列二 我们已经实现了socket的简单通信 接下来我们测试一下&#xff0c;在时间应用的场景下&#xff0c;我们会快速且大量的传输数据的情况&#xff01; 1 class Program2 {3 static void Main(string[] args)4 {5 TCPListener tcp n…

Java项目:CRM客户管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括&#xff1a; 用户管理&#xff0c;系统管理&#xff0c;客户管理&#xff0c;客户服务&#xff0c;客户关怀, 销售机会&#xff0c;统计管理等等。 二、项目运行 环境配置&#x…

Android 获取标题栏的高度

2019独角兽企业重金招聘Python工程师标准>>> 通过获取内容区域的 rect 的 top 值就是状态栏和标题栏的高度&#xff0c;也就可以得到标题栏的高度了&#xff0c; [java] view plaincopy int contentTop getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTo…

力扣—— 三维形体投影面积

在 N * N 的网格中&#xff0c;我们放置了一些与 x&#xff0c;y&#xff0c;z 三轴对齐的 1 * 1 * 1 立方体。 每个值 v grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上。 现在&#xff0c;我们查看这些立方体在 xy、yz 和 zx 平面上的投影。 投影就像影子&#xff0c;将…

一图带你入门Linux 存储I/O栈

发现了一个内核大佬 的 Linux 存储I/O栈&#xff0c;很清晰&#xff01;&#xff01;&#xff01; 原地址如下&#xff1a; http://ilinuxkernel.com/?p1559 【侵删】

Java项目:在线美食网站系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能&#xff1a;用户的注册登录&#xff0c;美食浏览&#xff0c;美食文化&#xff0c;收藏百 科&#xff0c;趣味问答&#xff0c;食谱等等功能等等。 二、项目运行 环境配置&#xff1a;…

性能测试中传——lr理论基础(四)

转载于:https://blog.51cto.com/fuwenchao/1346435

滑动定位的三种方法,以及热启动(五)

from init_driver.Init_driver import init_driverdriver init_driver()# 坐标-->坐标&#xff0c;定位滑动 driver.swipe(309, 1353, 537, 511, duration3000)# 元素-->元素&#xff0c;定位滑动 start_ele driver.find_element_by_xpath("//*[contains(text, 通…

TitanDB GC详细实现原理 及其 引入的问题

文章目录1. 为什么要有GC2. GC的触发条件3. GC的核心逻辑1. blob file形态2. GC Prepare3. GC pick file4. GC run4. GC 引入的问题5. Titan的测试代码通过本篇&#xff0c;能够从TitanDB的源代码中看到 key/value 分离之后引入的一些复杂性&#xff0c;这个复杂性很难避免。 …

Java项目:医院住院管理系统(java+SSM+jsp+mysql+maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括&#xff1a; 住院病人管理&#xff0c;住院病房管理&#xff0c;医生管理&#xff0c;药品管理&#xff0c;仪 器管理等等。 二、项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.…

1m网速是什么意思,1m带宽是什么意思

1M网速下载速度应是多少&#xff1f;我怎么才50多KB&#xff1f;&#xff1f; 建议: 一般来说是90到100算正常。最高能达到120 带究竟该有多快 揭开ADSL真正速度之谜 常常使用ADSL的用户&#xff0c;你知道ADSL的真正速度吗&#xff1f;带着这个疑问我们将问题一步一步展开。…

泛型实体类List绑定到repeater

泛型实体类List<>绑定到repeater 后台代码&#xff1a; private void bindnewslist(){long num 100L;List<Model.news> news _news.GetList(out num);this.newslist.DataSource news;this.newslist.DataBind();} 说明&#xff1a;Model.news是实体类&#xff0c…