Java基础(二)

172 阅读8分钟

一、多线程

1、进程的概念
应用程序例如(QQ.exe)在运行时所占用的独立的系统资源(内存、磁盘、CPU等等),进程是系统进行资源分配和调度的一个独立单位
2、线程
在进程资源内执行的多个任务单元,这些任务单元可以理解为线程,线程是进程的一个实体,是CPU调度和分派的基本单位
3、多线程
如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称之为多线程
4、多线程的特点
(1)提升了系统的CPU利用率
(2)节省了系统资源
(3)多个线程之间会争夺CPU资源
5、使用线程的步骤:
定义线程--创建线程对象--启动线程--终止线程

二、线程的创建

1、继承Thread类,并重写run方法

    public class 线程类 extends Thread{
	                .....
	        public void run(){
	                .....
            }
       }

2、实现Runnable接口,重写run方法

   public class Run线程类 implements Runnable{
	               .....
	        public void run(){
	               .....
            }
       }

3、创建线程对象的方式
(1)继承Thread类的创建对象方式
线程类 对象=new 线程类();
例如RabbitThread rabbit=new RabbitThread();

(2)实现Runnable接口的创建对象方式

 Run线程类 r=new Run线程类();
 Thread th=new Thread(r);

例如

TurtleRunnable turtle=new TurtleRunnable();
Thread tur=new Thread(turtle);

4、线程的启动
(1)使用线程对象调用start( )方法,即启动线程
(2)当start( )方法调用时,线程中的run( )方法会自动执行
注意:在实际中推荐使用实现Runnable接口线程类创建对象方式

三、线程的生命周期(5个状态)

1、创建状态New
创建线程对象过程
2、就绪状态Runnable
3、运行状态Running
start方法被调用时,线程的状态
4、阻塞状态Blocked
线程被挂起或者休眠等被阻塞执行的状态,线程所占用的资源并未销毁。随时转入可运行状态
5、死亡状态Dead
线程任务执行完成,或者系统退出,都会导致线程死亡

四、线程的调度

1、调度的主要目的是为了控制线程的执行顺序
2、调度的类型
(1)调整线程的优先级(建议操作系统调用优先级高的线程先执行)
void setPriority(int n);//n=0...9之间,1最低,默认优先级为5
(2)线程休眠(让出资源供其他线程使用)
Thread.sleep(休眠的时长毫秒);
(3)线程加入,在当前线程中调用另一个线程的join( )方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态,join应该在线程启动后start( )后执行
void join();
(4)线程让步,暂停当前线程的执行,让其他线程先执行,但是其他线程如果未争取到资源, 则继续执行当前线程。使用yield( )方法应该在线程启动后start( )后执行
Thread.yield();
(5)中断线程void interrupt();
(6)测试线程是否处于活动状态boolean isAlive();

五、常见线程名词解释

主线程:JVM调用程序main()所产生的线程
当前线程:这个是容易混淆的概念。一般指通过Thread.currentThread()来获取的进程
后台线程:指为其他线程提供服务的线程,也称为守护线程。JVM的垃圾回收线程就是一个后台线程。用户线程和守护线程的区别在于,是否等待主线程依赖于主线程结束而结束
前台线程:是指接受后台线程服务的线程,其实前台后台线程是联系在一起。由前台线程创建的线程默认也是前台线程。可以通过isDaemon()和setDaemon()方法来判断和设置一个线程是否为后台线程。

线程类的一些常用方法
  sleep( ): 强迫一个线程睡眠N毫秒
  isAlive( ): 判断一个线程是否存活
  join( ): 等待线程终止
  activeCount( ): 程序中活跃的线程数
  enumerate( ): 枚举程序中的线程
  currentThread( ): 得到当前线程
  isDaemon( ): 一个线程是否为守护线程
  setDaemon( ): 设置一个线程为守护线程
  setName( ): 为线程设置一个名称
  wait( ): 强迫一个线程等待
  notify( ): 通知一个线程继续运行
  setPriority( ): 设置一个线程的优先级

六、线程同步

1、当多个线程共享同一个资源时,需要使用线程同步,对共享的资源进行锁定,保证每次只能有一个线程使用该资源
2、锁定的资源可以是对象或者使用对象的方法
3、同步锁定的语法(synchronized关键字[ˈsɪŋkrənaɪzd])
 (1)语法1:同步方法

 public synchronized 返回值类型 方法名(参数){
	            ......
         } 

 (2)语法2:同步代码块,使用同步代码块,必须要设置一个锁定的对象,一般可以锁当前对象this

       synchronized(对象){
             ......
          }

4、使用synchronized锁定的方法或者代码块,在同一时间,只能有一个线程去调用此方法或者块中的资源对象,其他线程不能使用
注意:在List集合的实现类中,ArrayList是非线程安全的,Vector类是线程安全的

5、使用synchronized,会导致系统的资源利用率降低,但安全性提升

6、线程同步的目的是为了保证数据的安全

七、网络编程

1、计算机网络分类:局域网、 城域网、 广域网、 互联网等等
2、IP
(1)Internet协议
(2)对网络上的计算机进行标识
(3)ip地址的构成
由4个8位的2进制数据构成,为便于记忆,转换为十进制进行记忆 例如:192.168.0.1
IP地址 = 网络地址 +主机地址
网络地址:标识计算机或网络设备所在的网段
主机地址:标识特定主机或网络设备
注意:每个十进制数取值范围:0-254(1-255)
(4)使用域名绑定ip地址,在访问网站时可使用域名访问,而不是用ip地址访问域名
(5)查看本机的IP地址ipconfig
(6)测试网络是否通畅ping 目标IP地址
3、参考模型

4、端口
端口是虚拟的概念,通过端口,可以在一个主机上运行多个网络应用程序。MySQL(3306),Oracle(1521),Tomcat(8080)等等
查看端口:
查看所有端口:netstat -ano
查看具体程序:使用任务管理器查看PID

5、InetAddress类
InetAddress类表示互联网协议 (IP) 地址,InetAddress类没有构造方法,所以不能直接new出一个对象; 可以通过InetAddress类的静态方法获得InetAddress的对象。例如:InetAddress ip = InetAddress.getLocalHost();
常用方法
返回此 InetAddress 对象的原始 IP 地址
byte[] getAddress();
在给定主机名的情况下确定主机的 IP 地址
static InetAddress getByName(String host);
返回 IP 地址字符串(以文本表现形式)
String getHostAddress();
获取此 IP 地址的主机名
String getHostName();
返回本地主机
static InetAddress getLocalHost();

6、Socket简介
可理解为连接客户端与服务器端的端点(套接字),是提供给应用程序的接口,类似于物流中的“快递点”

八、基于TCP协议的Socket编程

1、TCP(Transmission Control Protocol)称为传输控制协议,是面向连接的传输层协议

1)服务器端编程
a、创建ServerSocket对象,绑定服务器端口地址
ServerSocket serverSocket=new ServerSocket(端口号);
注意:端口号在计算机中是唯一的,取值范围:0--65534,能用的从8000开始
b、使用ServerSocket对象接收客户端的请求,并得到一个Socket对象
Socket socket=serverSocket.accpet();
c、使用输入流从Socket中接收客户端传递的数据
InputStream in=socket.getInputStream();
d、将输入流的数据传递给字节数组

byte [] b=new byte[in.avilibel()];
in.read(b);

2)客户端编程步骤
a、创建Socket对象,绑定服务器的地址和端口号
Sokcet clinetSocket=new Sokcet("服务器的ip地址",服务器的端口号);
b、将要传递的数据转为字节数组
c、通过Socket 。对象获取输出流对象,准备输出数据流到Socket中
OutputStream out=clinetSocket.getOutputStream();
d、将字节数组写出到Socket中
out.write(字节数组);
注意:在运行时,应先启动服务器

九、基于UDP协议的Socket编程

1、UDP(User Datagram Protocol)又称为数据报传输协议
2、TCP是可靠的连接,TCP就像打电话,需要先打通对方电话,等待对方有回应后才会跟对方继续说话,只要两台机器上建立起了连接,在本机上发送的数据就一定能传到对方的机器上;
UDP就好比发电报,发出去就完事了,对方有没有接收到它都不管,所以UDP是不可靠的
TCP传送数据虽然可靠,但传送得比较慢;UDP传送数据不可靠,但是传送得快
3、UDP编程的主要步骤
1)服务器端
a、创建接受的报文套接字对象
DatagramSocket reciverSocket=new DatagramSocket(接收的端口号);
b、创建数据报对象
DatagramPacket reciverPackage=new DatagramPacket(字节数组,字节数组长度);
c、使用接收的套接字对象接收数据给数据报对象
reciverSocket.reciver(reciverPackage);
d、将数据报对象中的数据传递给字节数组
byte[] b=reciverPackage.getData();

2)客户端
a、创建发送的数据报文套接字对象
DatagramSocket sendSocket=new DatagramSocket();
b、创建发送的数据报对象
DatagramPacket sendPackage=new DatagramPacket(字节数组,数组长度, 接受方的InetAddress对象,接收方的端口号);
c、使用数据报套接字发送数据
sendSocket.send(sendPackage);