package com.yusian.socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class WebServer {
public static void m[......]
使用Socket通讯实现简单的Web服务器
Leave a reply
package com.yusian.socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class WebServer {
public static void m[......]
package com.yusian.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketDemo {
public static void main(String[] args) {
// 服务端进程
new Thread(() -> {
try {
// 创建一个Socket服务
ServerSocket ss = new ServerSocket(8080);
// 获取Socket的字节输入流对象,此时程序会阻塞在这个位置,直到有数据
InputStream is = ss.accept().getInputStream();
int data = 0;
// 将接收到的数据输出到控制台
while ((data = is.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
// 客户端进程
new Thread(() -> {
try {
// 创建一个Socket客户端,连接到指定服务器
Socket s = new Socket("localhost", 8080);
// 获取Socket的字节输出流,将数据从这里发出
OutputStream os = s.getOutputStream();
os.write("Hello Socket...".getBytes());
// 注意:要主动结束数据发送,否则对方会一直处于等待状态
s.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
[……]
FileInputStream、FileOutputStream
// IO流的读取与写入
private static void demo01() throws IOException {
// 如果是追加内容,则使用第二个参数为true的重载构造函数
FileOutputStream fos = new FileOutputStream("1.txt");
fos.write(97);
fos.write(98);
fos.write(99);
fos.close();
FileInputStream fis = new FileInputStream("1.txt");
// 字节读取返回的是读取的字节十进制值,并且自动向后偏移,如果返回-1则表过读取完毕
int data = fis.read();
System.out.println((char) data);
fis.close();
// 一次读取多个字节
FileInputStream fis2 = new FileInputStream("1.txt");
int length = 0;
byte[] bytes = new byte[1024];
while((length = fis2.read(bytes)) != -1) {
System.out.print(new String(bytes, 0, length));
}
fis2.close();
}
FileReader、FileWrite
// 字符流的读取与写入
private static void demo02() throws IOException {
// 如果是追加,则第二个参数传true
FileWriter fw = new FileWriter("1.txt");
fw.write(new char[]{'中', '国'});
// 字符的写入是先保存在内存缓存区,需要调用flush方法才会真正的写入到文件
fw.flush();
// 单个字符读取
FileReader fr = new FileReader("1.txt");
// 文件的读取会以字符的单位一个一个读取,如果返回值为-1则表示读取完毕
int c = fr.read();
System.out.println((char) c);
// 一次读取多个字符
FileReader fr2 = new FileReader("1.txt");
int length = 0;
char[] charArray = new char[1024];
while((length = fr2.read(charArray)) != -1) {
System.out.print(new String(charArray, 0, length));
}
fr2.close();
}
关于换行符号
[……]
synchronized关键字或Lock来实现;while或其他循环方法来获取当前状态,是该等待还是通知对方;wait或notify方法来实现的;商品对象类
/**
* 商品描述类,当前只是简单地标记商品的有与无
*/
public class Goods {
// 是否还有库存
boolean isEmpty;
public Goods() {
this.isEmpty = true;
}
}
消费者
/**
* 消费者模型
*/
public class Consumer extends Thread {
Goods goods;
public Consumer(Goods goods) {
this.goods = goods;
}
@Override
public void run() {
// 循环检测
while (true) {
// 同步执行
synchronized (goods) {
// 如果库存不为空则开始消费,消费结束后,将库存标记为空
if (!goods.isEmpty) {
System.out.println("---------------------");
System.out.println("消费");
try {
Thread.sleep(1000);
System.out.println("...");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("需求");
goods.isEmpty = true;
}
// 通知生产,当前线程等待,直接到生产唤醒
goods.notify();
try {
goods.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
生产者
[……]
多个线程访问共享数据就会产生冲突的问题,以卖票为例,多个窗口卖同一批票就会出现重复卖的问题
public static void main(String[] args) {
Runnable runnable = new Runnable() {
Integer tickets = 100;
@Override
public void run() {
String name = Thread.currentThread().getName();
while(tickets-- > 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "正在卖票: " + tickets);
}
}
};
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
}
解决方案一:使用同步机制,共享部分同步执行则不会出现重复操作问题
synchronized关键字实现代码块同步
public static void main(String[] args) {
Object lock = new Object();
Runnable runnable = new Runnable() {
Integer tickets = 100;
@Override
public void run() {
String name = Thread.currentThread().getName();
while (true) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock) {
if (tickets <= 0) break;
System.out.println(name + "正在卖票: " + tickets);
tickets--;
}
}
}
};
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
}
synchronized同步方法实现同步机制
static Integer tickets = 100;
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
sellTicked();
if (tickets <= 0) break;
}
}
};
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
}
synchronized private static void sellTicked() {
if (tickets <= 0) return;
String name = Thread.currentThread().getName();
System.out.println(name + "正在卖票: " + tickets);
tickets--;
}
解决方案二:使用锁,ReentrantLock
[……]