1、Socket编程
Socket(套接字):封装着如端口号,ip地址,计算机名等信息的类。通过Socket我们可以和远程计算机通信。
网络通信模型
C/S Client/Server
客户端通航运行在用户的计算机上,客户端是一个特有的程序,实现特有的功能,连接服务器进行通信,谁发起连接谁是用户。
服务器端通常是等待客户端连接,提供功能服务并与之通信。
B/S
固定了客户端和通信协议和C/S结构。
通信协议:计算机通信的实质就是相互收发字节。那么按照一定的格式收发字节就是通信协议。
一个最简单的网络通信:
1 | /** |
2、多线程Socket
Server端多线程:
服务器端无限循环接受客户端的访问,每连接都能茶圣一对新的Socket的实例。
为每个客户端连接创建一个独立线程,处理客户请求。
1 | public static void main(String[] args) { |
3、线程池
上面这种频繁的创建线程和销毁线程是非常消耗资源和性能的。
可以创建一些空的线程,将它们保存起来,当有任务需要并发执行时,我们取出一个空的线程来运行这个任务,当任务运行完毕后,在将线程收回,等待下次分配任务。
这样自始自终我们都只使用了开始创建的那些线程,并可以重复利用来节省性能开销。
JDK提供了线程池的管理器ExecutorService
通过Executors类的静态方法创建几个不同实现的线程池。
Executors.newCachedThreadPool();创建一个缓存线程池,当有任务的时候会检查线程池中是否有空线程,若有就使用它,若没有就创建新的线程。若长久没有使用的线程会自动回收。
Executors.newFixedThreadPool(int threads);创建一个可重用的,具有固定线程数的线程池。
Executors.newScheduledExecutor();创建只有一条线程的线程池,它可以在指定延迟后执行线程任务。
Executors.newSingleThreadExecutor();创建一个只有单线程的线程池,相当于Exceutors.newFixedThreadPool方法时传入参数1。里边维护着一个任务队列。
1 | /** |
4、双端队列
内部由两个队列实现,他们交替进行存取工作。这样至少可以保证2个线程同时进行存取操作。但是对于两个线程同时进行存或者取,还是要求同步的。
但是比单队列实现线程安全还是要快的。
BlockingDeque双端队列
实现:
1)ArrayBlockingDeque该类实现的构造方法要求我们传入一个整数,代表当前队列的长度。所以这个是一个固定大小的双端队列,存取原则为FIFO先入先出的原则。
当元素调用offer存入了队列时,若队列已满,那么可以设置延时等待,当超过了延时等待会返回存入失败。
2)LinkedBlockingDeque变长双端队列。长度不定,随着元素数量而增加,最大可以达到Integer.MAX_VALUE,重载构造方法可以传入一个整数,使之变为一个定长的队列。
3)PriorityBlockingDeque 这个和LinkedBlockingDeque相似,只不过是进去了自然排序后获取。
4)SynchronousQueue特殊的双端队列 存取步骤有要求,必须存一次取一次,交替进行。
例:
服务端
1 | /** |
客户端:
1 | public static void main(String[] args) { |
http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html这里有一篇文章讲的比较细,把地址记录下来,供查询,感谢作者。