Java与数据库、多线程介绍
java web
web: 蜘蛛网,网络
java core se standard edition 标准版(核心的类库)
java.lang.
java.util.
…
目前通过java se 可以开发(本地)“java应用程序” ,
java.io.*
IO, 程序与硬盘交流。
jdbc: java database connectivity
程序与数据库的交流。
软件开发: 数据+行为
如何实现java在web中的数据交互呢?
不同的java程序之间如何“通讯”。(网络)中数据的传输。
场景:
一条电脑中的java程序与另一条电脑(远端)java程序,进行数据的交流。
java与数据库的连接。
数据库的厂商要提供“相应语言的可以操作他的数据库产品的”相应的文件。
例: mysql-connector.8.0.24.jar。 class jar
对于java而言,如何连接的呢?
- 导包
- 注册驱动
- 获取数据库的连接对象(url, username, password)
- 获取数据库的操作对象(语句,预处理语句对象,结果集对象)
url: 需要有一定的“协议”
jdbc:mysql://localhost:3306/java2212
http://
“协议”(遵循的某种约定,规范)
数据库传输遵循的协议。
网络中的数据传输,也要遵循协议。
tcp : Transmission Control Protocol
IP: Internet Protocol
http: Hyper Text Transfer Protocol
port: 端口号 一个设备需要进行网络连接。
逻辑的地址2个字节表示 0~65535
mysql: 3306 , 80, 1521 …
0~1024尽量不要使用
是一个简单的请求-响应协议,它通常运行在TCP之上。
============ ==
场景:
一条电脑中的java程序与另一条电脑(远端)java程序,进行数据的交流。
如果让一个程序连接到网络中的另一个程序。
- 网络中走什么协议(tcp)
- 地址(ip, port)
现实:
java怎么实现以上的tcp,ip,port。
我们自己写一个“tcp"连接相关的类吗?需要调用一些网络上协议方式,产生连接吗?
jdk中提供java网络编程的方式。(tcp + udp)
java.net.ServerSocket
java.net.Socket
思路:
-
网络中进行通讯,通过socket(套接字) 理解为“管道”
需要建立“管道”进行数据的传输。 -
c/s的架构(客户端,服务器)
Server 服务器, service
Client 客户端
例1:
客户端连接到服务器,服务器给客户端发送一个“文本信息”(“welcome”),
客户端接收到这个文本信息。
练习:
客户端连接到服务器,客户端发送消息(hello server)给服务器,服务器显示出来。
底层的数据传输已经完成。
技术上,我们实现了。
客户端与服务器的连接,并且完成了数据的输入和输出!
问:
服务器,与“多个客户端”连接,才是服务器!
- 如何让服务器与多个客户端连接?
while(true) {
Socket socket = ss.accept();
//socket操作!
}
===========
//死循环, 无限循环,可以配合 等待的语句不会让程序奔溃。
- 发送数据,只有发送一次,可以发送“多次”数据吗?
//问题:
//希望发送不确定次数的数据、
while(true) { //外层循环,用于接收不同的客户端!
while(true) { //内存循环,用于接收到客户端的“多次”数据!
}
}
//造成的结果是,外层循环的第二次循环体的语句(无法到达)
- 要么发送,要么接收。 可以同时“既发送又接收数据”吗?
/*我们希望能够, 随时可以发送数据,可以“立即”接收数据。并且
这2件事情,不要有“逻辑关系”。
问题是,按照现有的java的运行机制,我们的写法是:*/
while(true) {
接收数据
}
while(true) {
发送数据
}
练习:
- 服务器接收一个客户端的多条数据
- 服务区接收多个客户端,每个客户端发送一条数据
java程序运行的机制:
对象: 堆内存
方法: 栈内存
双重(无限)循环
while(true) {
statement1
while(true) {
statement2
}
}
多次(无限)循环
while(true) {
statement1
}
while(true) {
statement2
}
按照java 方法按照线程的filo的机制,有些语句无法执行 unreachable
java特点
java的特点:简单! 语法与c类型,销毁对象!
java的特点:多线程! 有多个执行的空间!
垃圾回收器,回收垃圾(没有被引用的对象)java不需要(主动地)销毁对象。
只要放弃对对象的引用。对象就会被“垃圾回收器”回收!
我们只要new,不需要destory。。那是因为有人帮我们做到“垃圾回收器”。
“垃圾回收器”,什么时候帮我们销毁对象!
在java中,有隐含角色(线程调度器)
线程与进程介绍
我们程序执行,以main作为程序的入口。开启一个“主线程”。
同时,还会“自动”开启一些“守护”线程,帮忙做销毁对象,
一般来说,内存不足,或者主线程“休息”的时候。
线程调度器,执行“守护”线程的动作!
线程,(一个程序中的执行空间)
进程(程序)
win10,11
command line :286,386,486,586
一次执行一个任务。
win95 window视窗
多媒体多任务操作系统!
底层原理是为什么?
计算机的计算的资源分配,“最小的时间片段”只能由一个程序执行。
如果把“最小的时间片段”切到足够小,切换的速度“足够快”,可以让
人类以为多个程序“同时”执行。
线程是进程的“执行单位”,一个java进程中,可以有多个线程。
不同的线程,也能“同时”执行!通过“线程调度器”来决定由哪个线程执行。
线程之间是竞争的关系,“抢着”被自己线程的“任务”执行完成。
java语言的特点: 多线程。
具体而言:就可以“编程”式的“创建”,“操作”线程,达到“同时”执行的目的!
提供的相应的api,让线程即“随机”又“可控”!
Thread的状态
- 新建
- 可执行
- 执行
- 阻塞(等待,休眠)
- 死亡
线程类提供了,“主动”休眠本线程的方法。
Thread.sleep(millisSeconds)
创建新的线程
//方式1: 定义一个extends Thread的类
//在本类型指定任务。
class MyThread extends Thread {
public void run() {
。。。
}
}
main Thread:
MyThread t = new MyThread();
t.start();
方式2: 定义一个类Task 实现Runnable接口
创建新的线程,把任务传入
class MyTask implements Runnable {
public void run() {
。。。
}
}
main:
Runnable task = new MyTask();
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
案例: 火车票的售票 100 3个窗口同时买票!
1,2,3,。。。。100
线程同步
不同的线程对同一个“资源”进行操作,就可能产生线程不同步的问题。
原子: 不可分割。
statement1
statement2
statement3
statement4
thread1 thread2
银行汇款。账户1转账给账户2,10块钱。
account1 100
account2 0
account1 100 - 10 = 90
account2 0+10 = 10
原子:同步同时变化。
对数据加锁!
每个对象都有一个锁,默认是开启的状态。我们可以利用对象的锁。把语句变得“原子”。
练习:
银行账户100块
两个人,
其中一个人是通过手机银行取钱,每次取10块。一直取到0元。 thread1
另一个人是通过银行卡取钱,每次取10块。一直取到0元。 thread2
解决线程同步问题。 数据不一致!
核心的思路:让语句“原子”。
怎么做才能让语句原子。
可以利用对象,加锁。 每个对象默认一个“锁”。
不使用多线程遇到问题
遇到的问题1:服务器对多个客户端,每个客户端都接收信息,解决不了。
//产生的问题:程序始终运行在对第一个客户端接收信息。
while(true) {
//连接客户端
while(true) {
//接收客户端的信息
}
}
遇到的问题2:希望既可以接收信息,同时,有可以发送信息。但是第一个循环是“不断”地接收信息。
//接收信息的语句,无法结束。造成,无法发送信息。
while(true) {
//接收信息
}
while(true) {
//发送信息
}
客户端接收数据的技术,以及实现。
业务约定:
- 客户端发送数据给服务器,服务器接收到数据。并且将数据返回给客户端。(客户端-服务器-客户端)
- 在1的基础上,服务器把数据发回给“所有”的客户端。(群发)
- 如何私发消息(1个客户端对指定的另一个客户端发送信息)
程序运行后线程数量
服务器的线程数量:1+N
客户端的线程数量:1+1
程序的数量 1(服务器)+N(客户端)
线程,程序(java程序)