多线程基础 、 TCP通信    

* 当一个方法被synchronized修饰后,那么
 * 该方法称为同步方法,即:多个线程不能同时
 * 进入到方法内部执行。

  1. package day10;
  2. /**
  3. * 当多线程并发操作同一资源时,由于线程切换的不确定
  4. * 性,可能导致执行顺序的混乱,严重时可能导致系统
  5. * 瘫痪。
  6. * @author adminitartor
  7. *
  8. */
  9. public class SyncDemo1 {
  10. public static void main(String[] args) {
  11. final Table table = new Table();
  12. Thread t1 = new Thread(){
  13. public void run(){
  14. while(true){
  15. int bean = table.getBean();
  16. Thread.yield();//模拟线程切换
  17. System.out.println(getName()+":"+bean);
  18. }
  19. }
  20. };
  21. Thread t2 = new Thread(){
  22. public void run(){
  23. while(true){
  24. int bean = table.getBean();
  25. Thread.yield();//模拟线程切换
  26. System.out.println(getName()+":"+bean);
  27. }
  28. }
  29. };
  30.  
  31. t1.start();
  32. t2.start();
  33. }
  34. }
  35.  
  36. class Table{
  37. private int beans = 20;
  38. /**
  39. * 当一个方法被synchronized修饰后,那么
  40. * 该方法称为同步方法,即:多个线程不能同时
  41. * 进入到方法内部执行。
  42. * 在方法上使用synchronized那么锁对象为
  43. * 当前方法所属对象,即:this
  44. * @return
  45. */
  46. public synchronized int getBean(){
  47. if(beans==0){
  48. throw new RuntimeException("没有豆子了!");
  49. }
  50. Thread.yield();//模拟线程切换
  51. return beans--;
  52. }
  53. }

SyncDemo1.java

* 有效的缩小同步范围可以在保证并发安全的前提下
 * 提高并发效率。

  1. package day10;
  2. /**
  3. * 有效的缩小同步范围可以在保证并发安全的前提下
  4. * 提高并发效率。
  5. * @author adminitartor
  6. *
  7. */
  8. public class SyncDemo2 {
  9. public static void main(String[] args) {
  10. final Shop shop = new Shop();
  11. Thread t1 = new Thread(){
  12. public void run(){
  13. shop.buy();
  14. }
  15. };
  16. Thread t2 = new Thread(){
  17. public void run(){
  18. shop.buy();
  19. }
  20. };
  21. t1.start();
  22. t2.start();
  23. }
  24. }
  25.  
  26. class Shop{
  27. public void buy(){
  28. try {
  29. Thread t = Thread.currentThread();
  30. System.out.println(t.getName()+":正在挑选衣服...");
  31. Thread.sleep(5000);
  32. /*
  33. * 多个线程要保证同步执行代码的前提是
  34. * 这里看到的"同步监视器"即:上锁的对象
  35. * 是同一个。
  36. */
  37. synchronized(this){
  38. System.out.println(t.getName()+":正在试衣服...");
  39. Thread.sleep(5000);
  40. }
  41. System.out.println(t.getName()+":结账离开");
  42. } catch (Exception e) {
  43. e.printStackTrace();
  44. }
  45.  
  46. }
  47. }

SyncDemo2.java

* 每个类在被JVM加载时,JVM都会创建一个且只创建
 * 一个Class类型的实例来表示它。所以,每个类在
 * JVM内部都有唯一的一个Class类型的实例对应,而
 * 静态方法就是将该Class的实例上锁的。

  1. package day10;
  2. /**
  3. * 静态方法若使用synchronized修饰后,那么该方法
  4. * 一定具有同步效果。
  5. * 静态方法的同步监视器对象为当前类的类对象。
  6. * 类对象:Class类型的实例。
  7. * 每个类在被JVM加载时,JVM都会创建一个且只创建
  8. * 一个Class类型的实例来表示它。所以,每个类在
  9. * JVM内部都有唯一的一个Class类型的实例对应,而
  10. * 静态方法就是将该Class的实例上锁的。
  11. * @author adminitartor
  12. *
  13. */
  14. public class SyncDemo3 {
  15. public static void main(String[] args) {
  16. Thread t1 = new Thread(){
  17. public void run(){
  18. Foo.dosome();
  19. }
  20. };
  21. Thread t2 = new Thread(){
  22. public void run(){
  23. Foo.dosome();
  24. }
  25. };
  26. t1.start();
  27. t2.start();
  28. }
  29. }
  30.  
  31. class Foo{
  32. public synchronized static void dosome(){
  33. try {
  34. Thread t = Thread.currentThread();
  35. System.out.println(t.getName()+":正在运行dosome方法...");
  36. Thread.sleep(5000);
  37. System.out.println(t.getName()+":运行dosome方法完毕!");
  38. } catch (Exception e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }

SyncDemo3.java

* 互斥锁

  1. package day10;
  2. /**
  3. * 互斥锁
  4. * 当使用Synchronized修饰多段不同代码,但是同步
  5. * 监视器对象是同一个的时候,那么这些代码间就具有
  6. * 了互斥性,同一时间不能同时执行这些代码。
  7. * @author adminitartor
  8. *
  9. */
  10. public class SyncDemo4 {
  11. public static void main(String[] args) {
  12. final Boo boo = new Boo();
  13. Thread t1 = new Thread(){
  14. public void run(){
  15. boo.methodA();
  16. }
  17. };
  18. Thread t2 = new Thread(){
  19. public void run(){
  20. boo.methodB();
  21. }
  22. };
  23. t1.start();
  24. t2.start();
  25. }
  26. }
  27.  
  28. class Boo{
  29. public void methodA(){
  30. synchronized(this){
  31. try {
  32. Thread t = Thread.currentThread();
  33. System.out.println(
  34. t.getName()+":正在执行A方法");
  35. Thread.sleep(5000);
  36. System.out.println(
  37. t.getName()+":执行A方法完毕");
  38. } catch (Exception e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }
  43. public void methodB(){
  44. synchronized(this){
  45. try {
  46. Thread t = Thread.currentThread();
  47. System.out.println(t.getName()+":正在执行B方法");
  48. Thread.sleep(5000);
  49. System.out.println(t.getName()+":执行B方法完毕");
  50. } catch (Exception e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. }
  55. }

SyncDemo4.java

* 死锁

  1. package day10;
  2. /**
  3. * 死锁
  4. * 双方都持有自己的锁,但都要求对方先释放锁时
  5. * 出现死锁现象。
  6. * @author adminitartor
  7. *
  8. */
  9. public class SyncDemo5 {
  10. public static void main(String[] args) {
  11. final Coo coo = new Coo();
  12. Thread t1 = new Thread(){
  13. public void run(){
  14. coo.methodA();
  15. }
  16. };
  17. Thread t2 = new Thread(){
  18. public void run(){
  19. coo.methodB();
  20. }
  21. };
  22. t1.start();
  23. t2.start();
  24. }
  25. }
  26.  
  27. class Coo{
  28. private Object lockA = new Object();
  29. private Object lockB = new Object();
  30.  
  31. public void methodA(){
  32. try {
  33. Thread t = Thread.currentThread();
  34. synchronized (lockA) {
  35. System.out.println(t.getName()+"正在运行A方法");
  36. Thread.sleep(5000);
  37. methodB();
  38. System.out.println(t.getName()+"运行A方法完毕");
  39. }
  40.  
  41. } catch (Exception e) {
  42. }
  43. }
  44. public void methodB(){
  45. try {
  46. Thread t = Thread.currentThread();
  47. synchronized (lockB) {
  48. System.out.println(t.getName()+"正在运行B方法");
  49. Thread.sleep(5000);
  50. methodA();
  51. System.out.println(t.getName()+"运行B方法完毕");
  52. }
  53.  
  54. } catch (Exception e) {
  55. }
  56. }
  57. }

SyncDemo5.java

* 使用Collections的静态方法可以将现有的集合
 * 或Map转换为线程安全的

  1. package day10;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.HashMap;
  6. import java.util.HashSet;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.Set;
  10.  
  11. /**
  12. * 使用Collections的静态方法可以将现有的集合
  13. * 或Map转换为线程安全的
  14. * @author adminitartor
  15. *
  16. */
  17. public class Sync_API {
  18. public static void main(String[] args) {
  19. /*
  20. * 线程安全的集合自身的add,remove等方法
  21. * 都是同步的,并且之间也有互斥。
  22. * 但是并不与迭代器遍历互斥。所以若并发
  23. * 同时遍历和增删元素,迭代器依然会抛出
  24. * 异常。
  25. * 所以,迭代器与集合元素操作间要自行维护
  26. * 互斥关系。
  27. *
  28. * ArrarList,LinkedList都不是线程安全的
  29. */
  30. List<String> list
  31. = new ArrayList<String>();
  32. list.add("one");
  33. list.add("two");
  34. list.add("three");
  35. list.add("four");
  36. System.out.println(list);
  37. //将给定的集合转换为一个线程安全的集合
  38. list = Collections.synchronizedList(list);
  39.  
  40. System.out.println(list);
  41.  
  42. Set<String> set
  43. = new HashSet<String>(list);
  44. set = Collections.synchronizedSet(set);
  45. System.out.println(set);
  46.  
  47. Map<String,Integer> map
  48. = new HashMap<String,Integer>();
  49. map.put("语文", 100);
  50. map.put("数学", 99);
  51. map.put("英语", 98);
  52.  
  53. map = Collections.synchronizedMap(map);
  54. System.out.println(map);
  55. }
  56. }

Sync_API.java

* 线程池

  1. package day10;
  2.  
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5.  
  6. /**
  7. * 线程池
  8. * 线程池有两个主要作用:
  9. * 1:控制线程数量
  10. * 2:重用线程
  11. * @author adminitartor
  12. *
  13. */
  14. public class ThreadPool_Demo {
  15. public static void main(String[] args) {
  16. ExecutorService threadPool
  17. = Executors.newFixedThreadPool(2);
  18.  
  19. for(int i=0;i<5;i++){
  20. Runnable runn = new Runnable(){
  21. public void run(){
  22. Thread t = Thread.currentThread();
  23. System.out.println(t.getName()+":正在运行任务...");
  24. try {
  25. Thread.sleep(5000);
  26. } catch (InterruptedException e) {
  27. e.printStackTrace();
  28. }
  29. System.out.println(t.getName()+":运行任务完毕!");
  30. }
  31. };
  32. threadPool.execute(runn);
  33. }
  34.  
  35. //结束线程池
  36. threadPool.shutdown();
  37. System.out.println("线程池结束了!");
  38. }
  39. }

ThreadPool_Demo.java

案例一:

* 封装了TCP通讯的Socket
 * 使用它可以与服务端建立连接,并进行通讯

  1. package chat;
  2.  
  3. import java.net.Socket;
  4.  
  5. /**
  6. * 聊天室客户端
  7. * @author adminitartor
  8. *
  9. */
  10. public class Client {
  11. /*
  12. * 封装了TCP通讯的Socket
  13. * 使用它可以与服务端建立连接,并进行通讯
  14. *
  15. */
  16. private Socket socket;
  17. /**
  18. * 构造方法,用来初始化客户端
  19. */
  20. public Client() throws Exception{
  21. /*
  22. * 实例化Socket的过程就是连接服务端的
  23. * 过程。若连接失败,这里会抛出异常
  24. *
  25. * 构造方法的两个参数:
  26. * 1:服务端计算机的IP地址
  27. * 2:服务端应用程序的端口
  28. */
  29. socket = new Socket(
  30. "localhost",8088
  31. );
  32. }
  33. /**
  34. * 客户端开始工作的方法
  35. */
  36. public void start(){
  37.  
  38. }
  39.  
  40. public static void main(String[] args) {
  41. try {
  42. Client client = new Client();
  43. client.start();
  44. } catch (Exception e) {
  45. e.printStackTrace();
  46. System.out.println("客户端运行失败!");
  47. }
  48. }
  49. }

Client.java

* 聊天室服务端

  1. package chat;
  2.  
  3. import java.net.ServerSocket;
  4. import java.net.Socket;
  5.  
  6. /**
  7. * 聊天室服务端
  8. * @author adminitartor
  9. *
  10. */
  11. public class Server {
  12. /*
  13. * 运行在服务端的ServerSocket,主要作用:
  14. * 1:向操作系统申请服务端口,客户端就是通过
  15. * 这个端口与服务端程序建立连接的
  16. * 2:监听服务端口,一旦客户端连接了,就会创建
  17. * 一个Socket以便与该客户端交互
  18. */
  19. private ServerSocket server;
  20.  
  21. /**
  22. * 构造方法,用来初始化服务端
  23. * @throws Exception
  24. */
  25. public Server() throws Exception{
  26. /*
  27. * 初始化,并申请服务端口,若该端口被
  28. * 其他应用程序占用,这里会抛出异常
  29. */
  30. server = new ServerSocket(8088);
  31. }
  32.  
  33. public void start(){
  34. try {
  35. /*
  36. * ServerSocket提供方法:
  37. * Socket accept()
  38. * 该方法是一个阻塞方法,直到一个客户端
  39. * 通过申请的端口连接上,这里才会返回
  40. * 返回的是一个Socket实例,通过该实例
  41. * 即可与刚连接的客户端交互。
  42. */
  43. System.out.println("等待客户端连接...");
  44. Socket socket = server.accept();
  45. System.out.println("一个客户端连接了!");
  46.  
  47. } catch (Exception e) {
  48. e.printStackTrace();
  49. }
  50. }
  51.  
  52. public static void main(String[] args) {
  53. try {
  54. Server server = new Server();
  55. server.start();
  56. } catch (Exception e) {
  57. e.printStackTrace();
  58. System.out.println("服务端运行失败!");
  59. }
  60. }
  61. }

Server.java

JAVASE02-Unit010: 多线程基础 、 TCP通信的更多相关文章

  1. 性能测试基础 ---TCP通信过程的状态码与过程,以及出现错误码的分析(TIME_WAIT,CLOSE_WAIT)

    TCP通信过程 如下图所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手).数据传输.断开TCP连接通道(四次挥手). 这里进一步探究TCP三路握手和四次挥手过程中的状态变迁以及数据传输过 ...

  2. 多线程基础(五)NSThread线程通信

    5.多线程基础 线程间通信   什么叫线程间通信 在一个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信   线程间通信的体现 1个线程传递数据给另一个线程 在1个线程中执行完特定任务后, ...

  3. UE4 Sockets多线程TCP通信

    转自:https://blog.csdn.net/zilisen/article/details/75007447 一.简介 UE4引擎是提供了Sockets模块和Networking模块的,博主在研 ...

  4. Java基础教程:多线程基础(2)——线程间的通信

    Java基础教程:多线程基础(2)——线程间的通信 使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时还会使程序员对各线程任务在处理的过程中进行有效的把控与监督. 线程间的通信 ...

  5. TCP通信 - 服务器开启多线程与read()导致服务器阻塞问题

    TCP通信的文件上传案例 本地流:客户端和服务器和本地硬盘进行读写,需要使用自己创建的字节流 网络流:客户端和服务器之间读写,必须使用Socket中提供的字节流对象 客户端工作:读取本地文件,上传到服 ...

  6. TCP通信---文件上传案例、多线程文件上传

    目前大多数服务器都会提供文件上传的功能,由于文件上传需要数据的安全性和完整性,很明显需要使用TCP协议来实现. TCP通信需要创建一个服务器端程序和一个客户端程序,实现客户端向服务器端上传文件 代码实 ...

  7. 【Java TCP/IP Socket】深入剖析socket——TCP通信中由于底层队列填满而造成的死锁问题(含代码)

    基础准备 首先需要明白数据传输的底层实现机制,在http://blog.csdn.net/ns_code/article/details/15813809这篇博客中有详细的介绍,在上面的博客中,我们提 ...

  8. 多线程实现tcp聊天服务器

    多线程tcp  server & client tcp服务端(多线程): from socket import * from threading import Thread def clien ...

  9. Java进阶:基于TCP通信的网络实时聊天室

    目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...

随机推荐

  1. NetApp 监控

    http://support.ipmonitor.com/mibs/network-appliance-mib/tree.aspx http://www.360doc.com/content/10/1 ...

  2. .NET中RabbitMQ的使用

    概述 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public ...

  3. 【转】算法杂货铺——k均值聚类(K-means)

    k均值聚类(K-means) 4.1.摘要 在前面的文章中,介绍了三种常见的分类算法.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应.但是很多时 ...

  4. CozyRSS开发记录5-订阅列表栏里的项

    CozyRSS开发记录5-订阅列表栏里的项 1.订阅列表栏里的项的原型图 这里列表项依然参考傲游的RSS阅读器,以后可能会微调. 2.使用ControlTemplate来定制ListBoxItem 给 ...

  5. HDU 3015 Disharmony Trees(树状数组)

    题意:给你n棵树,每棵树上有两个权值X H 对于X离散化 :3 7 1 5 3 6 -> 2 6 1 4 2 5,对于H一样 然后F = abs(X1-X2)   S=min(H1,H2) 求出 ...

  6. 08 Servlet

    Servlet技术          * Servlet开发动态的Web资源的技术.                       * Servlet技术               * 在javax. ...

  7. 练练脑javascript写直接插入排序和冒泡排序

    function insertionSort(array) { if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') ...

  8. 集中式vs分布式区别

    记录一下我了解到的版本控制系统,集中式与分布式,它们之间的区别做下个人总结. 什么是集中式? 集中式开发:是将项目集中存放在中央服务器中,在工作的时候,大家只在自己电脑上操作,从同一个地方下载最新版本 ...

  9. 【BO】为WEBI报表添加自定义字体font

    本篇主要讲解如何为sap business objects 的web intelligence报表组件新增字体.因为系统默认预设的字体对中文而言实在是太丑了,有的字体特喵的直接把中文变成方框框了! 一 ...

  10. 2014亚马逊在线笔试题目及解决方案(MMChess问题)

    整体思路:关键是需要知道当前Steps数组中的全排列即可,而且需要不重复的全排列.即关键在于非递归的全排列实现即可~ 其实直接利用STL中的next_permutation算法的,这里我又自己实现了一 ...