线程与网络

线程和网络

线程

概念

​ 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的EXE就是一个进程。线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某一个进程,进程中的多个线程共享进程内存。

实现

定义线程
  1. 扩展java.lang.Thread类。
  2. 实现java.lang.Runnable接口。
启动线程

在线程的对象上调用start()方法。

在调用start()方法之前,线程处于新状态中,还没有成为一个真正的线程。在调用start()之后,线程从新状态转移到可运行状态,当线程获得机会执行时,其目标run()方法将运行。

[外链图片转存失败(img-CvWHHHHA-1566632794265)(C:\Users\Eryu\AppData\Roaming\Typora\typora-user-images\1566626199146.png)]

新状态

已经创建线程对象。还没有在其上调用start()方法。

可运行状态

当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态。当start()方法调用时,线程首先进入可运行状态,在线程运行之后或者从阻塞、等待或休眠状态回来后,也可以成为可运行状态。

运行状态

Runable状态中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态唯一的方式。

等待/阻塞/休眠状态

这是线程有资格运行时它所处的状态,三种线程实际上合为一种,线程任然是活的,但是当前没有条件运行。

死亡状态

当线程的run()方法完成时就认为它死去了。这个线程对象也许是活的,但是它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。如果在一个死亡的线程上调用start()方法,就会java.lang.IllegalThreadStateException

线程同步

  • 概念

    线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。

  • 锁的原理

    Java中每个对象都有一个内置锁

    当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步。

    当程序运行到synchronized同步方法或代码块时才该对象锁才起作用。

    一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。

    释放锁是指持锁线程退出了synchronized同步方法或代码块。

  • 关于锁和同步,有一下几个要点:

    1. 只能同步方法,而不能同步变量和类;
    2. 每个对象只有一个锁;当提到同步时,应该清楚在什么上同步?也就是说,在哪个对象上同步?
    3. 如果两个线程要执行一个类中的synchronized方法,并且两个线程使用相同的实例来调用方法,那么一次只能有一个线程能够执行方法,另一个需要等待,直到锁被释放。也就是说:如果一个线程在对象上获得一个锁,就没有任何其他线程可以进入(该对象的)类中的任何一个同步方法。
    4. 线程睡眠时,它所持的任何锁都不会释放。
    5. 同步损害并发性,应该尽可能缩小同步范围。同步不但可以同步整个方法,还可以同步方法中一部分代码块。
    6. 在使用同步代码块时候,应该指定在哪个对象上同步,也就是说要获取哪个对象的锁。
  • 举例:用多线程模拟3个窗口售卖火车票。

  • 线程的安全性

    当一个类已经很好的同步以保护它的数据时,这个类就称为“线程安全的”。

线程的互斥与死锁

  • wait()和notify()

    程序执行wait()时,线程进入等待状态
    程序执行notify()时,唤醒处于wait状态的线程

  • 使用wait()和notify()的注意事项

    wait()和notify()方法定义在Object类中,所以任何对象都可以调用,但是必须在synchronized同步方法或代码块才能调用,否则会产生异常。
    要尽量避免死锁发生。如果程序中两条线程都进入wait()状态,那么彼此无法唤醒对方,就进入到了死锁。
    如果进入wait状态的线程不止一条,调用notify()只能唤醒其中的一条,而且无法指定是哪一条。如果要全部唤醒,则可调用notifyAll()。

网络

两台或两台以上电脑通过网线连在一起就组成一个网络,网络编程就是两个或两个以上的设备之间的数据传输。

什么是网络通信协议?

网络通信协议就像我们的中文一样,她就是我们之间的共同语言,他规定了我们之间怎么说话,我先说什么你再说什么,你怎么说,而我应该怎么听。而网络通信得先规定约定一些俗成的网络通信协议,先说好,两台计算机之间什么收发信息,信息格式是什么,信息怎么发,怎么接收,而万一出错怎么办怎么处理。

OSI七层模型

[外链图片转存失败(img-hA2zh6AG-1566632794266)(file:///C:/Users/Eryu/Desktop/%E7%AC%94%E8%AE%B0/03.java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E9%AB%98%E7%BA%A7/%E7%AC%94%E8%AE%B0/javaOOPhigh04_04.jpg)]

ISO制定的OSI参考模型的过于庞大、复杂招致了许多批评。与此对照,由技术人员自己开发的TCP/IP协议栈获得了更为广泛的应用。

[外链图片转存失败(img-DR6XDZzT-1566632794268)(file:///C:/Users/Eryu/Desktop/%E7%AC%94%E8%AE%B0/03.java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E9%AB%98%E7%BA%A7/%E7%AC%94%E8%AE%B0/javaOOPhigh04_05.jpg)]

UDP和TCP

TCP和UDP都是传输层协议
网络应用中基本上都是TCP(Transmission Control Protocol传输控制协议)和UDP(User Datagram Protocol用户数据报协议),TCP是面向连接的通信协议,UDP是无连接的通信协议.

TCP协议特点

传输控制协议,提供的是面向连接、可靠的字节流服务。
当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。
TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

三次握手

[外链图片转存失败(img-3DWrMXQb-1566632794270)(file:///C:/Users/Eryu/Desktop/%E7%AC%94%E8%AE%B0/03.java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E9%AB%98%E7%BA%A7/%E7%AC%94%E8%AE%B0/javaOOPhigh04_03.png)]

UDP协议特点

UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。
UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。
由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,所以传输速度很快。

应用

TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽 ,因此TCP传输的效率不如UDP高。

UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。

[外链图片转存失败(img-MmbWK2lq-1566632794271)(file:///C:/Users/Eryu/Desktop/%E7%AC%94%E8%AE%B0/03.java%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E9%AB%98%E7%BA%A7/%E7%AC%94%E8%AE%B0/javaOOPhigh04_02.png)]

127.0.0.1是回路地址,用于测试,相当于localhost本机地址,没有网卡,不设DNS都可以访问.

端口地址在065535之间,其中01023之间的端口是用于一些知名的网络服务和应用,用户的普通网络应用程序应该使用1024以上的端口.

Socket连接套接字,Java分别为TCP和UDP提供了相应的类,TCP是java.net.ServerSocket(用于服务器端)和java.net.Socket(用于客户端);UDP是java.net.DatagramSocket.

Java编写UDP网络程序

类DatagramSocket介绍

DatagramSocket有如下构造方法:

  1. DatagramSocket() :构造数据报套接字并将其绑定到本地主机上任何可用的端口。
  2. DatagramSocket(int port):创建数据报套接字并将其绑定到本地主机上的指定端口。
  3. DatagramSocket(int port, InetAddress address):创建数据报套接字,将其绑定到指定的本地地址。即指定网卡发送和接收数据.

如果在创建DatagramSocket对象时,没有指定网卡的IP 地址,在发送数据时,底层驱动程序会自动选择一块网卡去发送,在接收数据时,会接收所有的网卡收到的与端口一致的数据.

发送信息时,可以不指定端口号,接收信息时,要指定端口号,因为要接收指定的数据.

发送数据使用DatagramSocket.send(DatagramPacket p)方法,接收数据使用DatagramSocket.receive(DatagramPacket p)方法.

类DatagramPacket介绍

DatagramPacket类有如下构造方法:

  1. DatagramPacket(byte[] buf, int length):构造 DatagramPacket,用来接收长度为length的数据包。
  2. DatagramPacket(byte[] buf, int length, InetAddress address, int port):构造数据报包,用来将长度为length的包发送到指定主机上的指定端口号。

接收数据时使用第一次构造方法,发送数据时使用第二种构造方法.

</
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值