Java_SE10-多线程,TCP通信

来源:互联网 发布:win10电脑mac地址修改 编辑:程序博客网 时间:2024/04/30 20:16

线程的同步

  1. 多线程并发安全问题,当多个线程操作同一资源时,由于线程切换的不确定性,会导致出现线程安全问题
  2. 当一个方法被synchronized修饰后,当前方法称为”同步方法”,多个线程不能同时进入方法内部执行,只能”排队执行”,要想解决多线程并发安全问题,就需要将执行代码从”异步”(各干干的)变为”同步”(排队干)执行
  3. 当在成员方法上使用synchronized,上锁的对象就是当前方法所属对象,即方法中看到的this
  4. 静态方法被synchronized修饰后,一定具有同步效果,静态方法的上锁对象为当前类的对象,Java中有一个名为Class的类,其每一个实例用于描述Java中的一个类,每当我们使用一个类时,JVM在读取该类class文件后都会创建一个Class的实例,来保存该类的信息,以便使用,所以在JVM内部,每一个类都有一个且只有一个Class的实例对应,静态方法就是给这个对象上锁的
  5. 同步块可以有效地缩小同步范围,同步块需要制定”同步监视器”,即上锁的对象,只要保证多个线程看到的该对象是同一个, 那么这些线程在执行器中代码时就具有”同步”效果,只能排队执行,通常使用this即可
  6. synchronized互斥锁的效果:当synchrnized将不同的代码片段修饰后,只要锁对象相同,那么这些代码是互斥的,多个线程不能同时进到这些不同方法中

线程安全的集合API

List集合常用API:ArrayList,LinkedList
Set集合常用API: HashSet
Map集合常用API: HashMap
以上集合常用API都不是线程安全的
可以通过Collections工具类的synchronptedxxx()方法来将其转换为线程安全的

线程池

  1. 池的概念:池通常使用储存多个相同内容的元素,使用池可以控制元素数量, 同时重用元素,对于元素的创建及销毁全部由池来完成
  2. 线程池:控制线程数量,并重用线程
  3. Executors.newCachedThreadPool();创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用他们
    Executors.newFixedThreadPool(int nThreads);创建一个可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程
    Executors.newScheduledThreadPool(int corePoolSize);创建一个线程池,它可安排在给定延迟后运行命令或者定期的执行
    Executors.newSingleThreadPool(int nThreads); 创建一个使用单个worker线程的Executor,以无界队列方式来运行该线程
  4. void execute(Runnable r);将创建的任务交给线程池
  5. 停止线程池有两个方法:
    shutdown()方法停止线程池,那么线程池会先将当前池中所有任务执行完毕,然后停止
    shutdownNow()方法停止线程池,那么线程池会立即停止
  6. BlockingQueue:双缓冲队列
    *在多线程并发时,既要满足同步安全又要提高效率
    *BlockingQueue允许两条线程同时向队列一个做存储一个做取出
    *boolean offerFirst(E e):从头添加元素;boolean offerLast(E e):从尾添加元素;
    *E poolFirst():从头取出元素; E poolLast():从尾取出元素;

TCP通信

  1. java.net.Socket封装了TCP通讯,使用该类完成与服务器端的连接,并进行相应的通讯
  2. 实例化Scoket时需要传入两个参数:
    *服务器端的地址—通过地址找到服务端的计算机
    *服务器端的端口—端口则找到该计算机上的服务端应用程序(端口尽量在2000~10000之间)
  3. 实例化Socket的过程就是连接服务端的过程,连接不成功该构造方法会抛出异常
  4. java.net.ServerSocket;运行在服务端的ServerSocket有两个作用:
    *申请服务端口(客户端通过该端口与服务端建立连接)
    *监听服务端口,等待客户端连接,一旦客户端连接则自动创建一个Socket实例用于与该客户端交互
  5. 实例化SercerSocket需要指定服务端口,该端口不能与当前操作系统其他程序申请的端口冲突,否则会抛出端口被占用异常
  6. ServerSocket提供了方法:Socket accept();该方法是一个阻塞方法,作用是监听ServerSocket开启的服务端口,知道一个客户端通过该端口连接,该方法才会解除阻塞,并返回一个Socket实例,通过该Socket实例与刚刚建立连接的客户端进行通讯
1 0