文章目录
1 多线程
1.1 线程的生命周期
- new完一个对象后对象得到创建 ----> 调用 start() 方法,处于就绪状态 ----> 可运行,在线程池中等待CPU
的使用权 ----> 获取CPU使用权 - 当收到某种原因的影响放弃CPU的使用权以后,暂时停止运行,直到再次就绪(Runnable)
- 因执行完毕或异常退出了 run() 方法,该线程生命周期结束(Dead)
三种阻塞 - 等待阻塞:运行的线程执行 wait() 方法,JVM 将其放入等待池,该方法还会释放持有的锁
- 同步阻塞:运行线程获取对象的同步锁时,若该方法被其他线程占用,JVM会将其放入锁池
- 其他阻塞:sleep() , join() 方法被执行或发出I/O请求时,JVM会把该线程置为阻塞。(sleep不会释放持有
的锁)
1.2 线程调度
设置优先级:
Thread类的 setPriority() 、 getPriority 方法设置、获取优先级
休眠(sleep)
编写时钟:
import sun.util.calendar.LocalGregorianCalendar;
...
...
Date date = new date();
System.out.println(date.toLocalString());//调用 toLocalString()
线程让步 yield()
Thread.yield()暂停正要执行的程序,把执行机会让给优先级不比它小的 :Threadx.getPriority() >=
this.getPriority。需要注意的是,yield() 方法处理完以后处于就绪状态,仍然参与竞争(不会被阻
塞)。
补充:getName() 方法可以得到线程的名称,setName(parameter) 方法设定
join() 调度
通过join()方法来阻断当前执行的进程,引进调用该方法的进程
补充:实现多线程的2种方式
方法一.直接调用继承Thread的类
public class ThreadDemo extends Thread{
@override
public void run(){
...
}
}
public static void main(String[] args){
ThreadDemo td = new ThreadDemo();
td1.start();
}
方法二.通过修改Thread内部参数
思路:修改Runnable的实例化(implements)对象 —>主函数调用Thread,同时修正Thread内部参数
public class RunnableDemo implements Runnable{
@Override
public void run(){
...
}
}
public class MainRunnableDemo{
public static void main(String[] args){
RunnableDemo rd = new RunnableDemo();
Thread td = new Thread(rd);
td.setName("新线程样例");
td.start();
}
}
1.3 线程同步
当多个线程同时使用一个资源时,在当前时间内,只允许一个线程使用共享资源,而其他线程处于等待
因此在Java中一般采用synchronized和Lock来实现同步互斥访问
- 方法同步处理
public synchronized returnType Name(){
...
}
使用此方法锁定对象,该方法中所有对象都会被锁定
2. 代码块同步
public void salary(int num){
synchronized(menpiao){//指明下述代码块中要同步的对象
...
}
}
想要访问到被synchronized修饰的对象时,必须获取到该方法或代码块的锁,若未获取须等待持有的线程释放该锁,释放锁只有两种情况:
①程序执行完代码块,自动释放;
②程序报错,JVM让线程自动释放;
1.4 线程通讯
通讯等待与线程唤醒:
Object类 | 作用 |
---|---|
Void wait() | 让活动在当前对象的线程无限等待(释放之前占领的内存) |
Void notify() | 唤醒当前对象正在等待的线程(仅唤醒,不释放持有的锁) |
Void notifyAll() | 唤醒此对象监视器上等待的所有线程 |
tips:
①wait 和 notify方法是Object对象自带的
②在处理多线程相关问题时优先使用 Vector集合,该集合中绝大部分方法都是带有同步的概念机制的
2. 网络编程
2.1 TCP\IP 编程
TCP(Transmission Control Protocol):传输控制协议
IP(Internet Protocol):Internet协议
查看本机IP的指令
ipconfig
查看另一个主机能否通讯
ping [另一台主机的名称]
2.2 ServerSocket(Java.net.ServerSocket)
2.2.1 ServerSocket的创建
Serversocket serversocket = new Serversocket(\*端口号*\);
2.2.2 接收客户端的数据并返回一个Socket对象
Socket socket = serversocket.accept();`
2.2.3 基于Socket的输入输出流
输入
BufferedReader is = new BufferedReader(new InputStream(socket.getInputStream()));
getInputStream()方法获取Socket输入流
输出
PrintWriter os = new PrintWriter(new OutputStream(socket.getOutputStream()));
os.println(...);
flush();
getOutputStream()方法获取Socket输出流
2.3 Socket(Java.net.Socket)
2.3.1 Socket的创建
Socket clientSocket = new Socket(/*ip地址*/,/*服务器端口号*/)
2.3.2 向服务器发送数据
OutputStream os = Socket.getOutputStream();
os.write(/*发送字节流数组*/);
2.3.3 接收服务器的数据
补充:
read() //表示读取所有数据,返回一个字符串或一个字节数组
read(size) //读取size长度的数据,返回一个字符串或一个字节数组
read(byte[]) //将.read前的对象的中读取到的数据写入byte[]数组
InputStream is = Socket.getInputStream();
byte[] b = new byte[1024];
is.read(b); /*将客户端接收到的数据存入字节流数组中*/
2.3.4关闭套接字
socket.close();
补充:
byte[] b = new byte[1024];
String str = new String(b, "utf-8");
system.out.println(str.trim());
trim的作用是去除两边的空格,保证得到数据的类型的简洁性、正确性。
Scanner
优点:可以读取字符兼字节数据(其他几种包括InputStream只能读取字符或字节流)
缺点:不能设置读取的字符编码,不能读取二进制数据(二进制数据是一种存储方式,InputStream可以读取
任何编码存储)
简单来说:Scanner可以根据数据的类型来获取数据,而其他几种输入只能获取字符或字节,但是Scanner不能
从字节输入流中获取数据,而InputStream可以从任何字节输入流中获取数据。