复习:
线程:
两种实现方式:
extends Thread
implements Runnable 不是线程类
构造方法:
Thread();
Thread(String name);
Thread(Runnable r);
Thread(Runnable r,String name)
常用方法:
run()线程体方法
start()启动线程
currentThread()返回正在执行的线程对象
getName()返回线程的名称
sleep() 线程休眠
join()等待线程执行结束
生命周期:
新建状态:new Thread()
就绪状态:start()
阻塞状态:sleep(),wait(),io,解除,重新排队
运行状态:run()执行方法,自动执行的
消亡状态:执行完run方法
优先级:
系统自动分配:5
人为设置:
调度:
不同优先级:高优先级先执行,低后
同一优先级:先到先服务
线程同步:
共享变量不安全
synchronized
synchronized(锁对象){
}
synchronized修饰方法
同步线程之间的通信问题
wait()
notify();
notifyAll();
-------------------------------------------------------------
sleep和wait的区别
sleep线程类的方法 wait是Object类的方法
sleep方法不是释放锁 wait是释放锁
sleep方法自动醒 wait必须使用notify,notifyAll唤醒
线程的死锁
StringBuffer str1 = new StringBuffer();
StringBuffer str2 = new StringBuffer();
synchronized (str1) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (str2){
System.out.println("str1");
System.out.println("str2");
}
}
synchronized (str2) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (str1){
System.out.println("str1");
System.out.println("str2");
}
}
线程池
为什么使用线程池
频繁的创建线程,需要耗费时间和内存
使用线程池的好处:
管理线程
使线程重用
package cn.tedu.demo.thread;
import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadPoolDemo {
//创建一个线程池,如果线程池中的线程数量过大,它可以有效的回收多余的线程,
// 如果线程数不足,那么它可以创建新的线程。
public static void test1() throws Exception {
ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
final int index = i;
Thread.sleep(1000);
//完成5个任务
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " " + index);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
//指定线程池中的线程数,线程数是可以进行控制的
public static void test2() throws InterruptedException {
// ExecutorService threadPool = Executors.newFixedThreadPool(1);
ExecutorService threadPool =
Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
final int index = i;
threadPool.execute(() -> {
try {
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + index);
});
}
threadPool.shutdown();//不关闭正在执行的线程
//threadPool.shutdownNow();//不管线程是否执行完毕,立即停止执行
System.out.println("关闭线程!");
}
//线程池支持定时周期性任务执行
public static void test3() {
ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
threadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
long start = new Date().getTime();
System.out.println("scheduleAtFixedRate 开始执行时间:" +
DateFormat.getTimeInstance().format(new Date()));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = new Date().getTime();
System.out.println("scheduleAtFixedRate 执行花费时间=" + (end - start) / 1000 + "m");
System.out.println("scheduleAtFixedRate 执行完成时间:" + DateFormat.getTimeInstance().format(new Date()));
System.out.println("======================================");
}
}, 1, 5, TimeUnit.SECONDS);
}
//单线程池,至始至终都由一个线程来执行
public static void test4() {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
final int index = i;
threadPool.execute(() -> {
try {
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + index);
});
}
// threadPool.shutdown();
}
public static void main(String[] args) throws Exception {
test2();
}
}
-------------------------------------------------------------
网络编程概述
计算机网络:
网络模型(OSI开放式系统互联。国际标准组织制定了OS七层网络模型I(Open System Interconnection)模型)
OSI七层网络模型
物理层 数据链路层 网络层 传输层 会话层 表示层 应用层
协议:事先规定好的通信规则
协议分类:共有的,私有的
网络层:ip
传输层:udp,tcp
应用层:ftp http https。。。
IP地址
IP地址:表示网络上的唯一一台计算机
IP地址分为两个版本:
IPv4 IPv6
端口:0-65535 (0-1024)预留的
域名解析:localhost(www.163.com):127.0.0.1(72.1.1.1)
java中的网络编程
1.UDP通信 -- 写信
不需要创建连接
通过发送数据包通信 每个数据包最大64KB
不可靠的传输机制
传输速度比较快
追求速度快 可靠性要求不高的场景下 - 视频聊天
2.TCP通信 -- 打电话
需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手
底层通过 流 发送数据 数据没有大小限制
可靠的传输机制 - 丢包重发 包的顺序的保障
传输速度相对比较慢
对于速度要求不太高 但是对可靠性要求比较高的场景下 - 文件上传 下载
因为TCP在通信的过程中 是需要创建连接的 连接的发起者称为客户端 监听端口等待被连接的一端称为服务端
服务器端的核心代码
//1.创建套接字对象
ServerSocket serverSocket=
new ServerSocket(5555);
System.out.println("等待客户端的请求。。。。。");
//2.调用accept方法,接收请求
Socket socket = serverSocket.accept();
System.out.println("接收到一个客户端的请求。。。。。。");
//3.获取输入流对象,读客户端的数据
InputStream in = socket.getInputStream();
BufferedReader br =
new BufferedReader(
new InputStreamReader(in));
String msg = br.readLine();
System.out.println(msg);
//4.处理后的结果通过输出流,写出去
msg = msg+ " hello,client!";
OutputStream out = socket.getOutputStream();
PrintStream pw = new PrintStream(out);
pw.println(msg);
pw.flush();
//5.关闭流,套接字对象
br.close();
pw.close();
socket.close();
serverSocket.close();
客户端的代码:
//1.创建套接字对象
Socket socket = new Socket("localhost",5555);
//2.获取输出流,写信息
OutputStream out =
socket.getOutputStream();
PrintStream pw =
new PrintStream(out);
pw.println("hello server!");
pw.flush();
//3.获取输入流,读信息
InputStream in = socket.getInputStream();
BufferedReader br =
new BufferedReader(
new InputStreamReader(in));
String msg = br.readLine();
System.out.println(msg);
//4.关闭流
pw.close();
br.close();
socket.close();
案例(了解):实现 文件 上传服务器