java多线程编程的两种方式:
/**
继承Thread类*/
pubilic class myThread extends Thread{
pubilc void run(){
system.out.print("")
}
}
new myThread().start();
/**
实现runnable接口*/
public class myRunnable implements Runnable{
public void run(){
system.out.print("")
}
}
new Thread(new myRunnable()).start();
解决线程安全的问题
- 同步代码块
- 同步方法
等待唤醒机制
- 生成一个对象,用于定义同一把锁
- 首先执行完逻辑之后,使用该对象.notify()唤醒另一条线程,之后在通过该对象.wait()使当前对象进入等待状态
- 同理,另一线程也是如此操作
文件NIO
- 写数据
- 创建输出流FileOutPutStream
- 根据这个流使用getChannel获取通道
- 新建缓冲区byteBuffer
- 使用put方法吧字节加入buffer中
- flip翻转缓冲区,获取正确的数据
- write方法吧buffer的内容写入到通道
- 关闭流
- 读数据
- 新建一个输入流
- 得到通道
- 准备缓冲区
- 从通道中读取数据导缓冲区
- 关闭流
网络NIO实例
- 服务器端首先得到监听通道和选择器,把选择器绑定到监听通道并监视其accept事件
- 不停地监控客户端,通过选择器的select方法去查找选择其中有无新信息进入,如果有就开始遍历存储在选择器中的key
- 再从通道中获取到数据写出来存入buff中,同时给通道中的其他进入通道的客户端发送广播
- 客户端开启线程不停地监听通道是否有数据在通道中进行广播
- 客户端
public static void main (String[] args){
SocketChannel channel= SocketChannel.open();//得到一个通道
channel.configureBlocking(false);//设置非阻塞方式
InetSocketAddress address=new InetSocketAddress("127.0.0.1",9999);//提供服务器的Ip地址和端口号
if(!channel.connect(address)){//链接服务器
while(!channel.finishConnect()){
System.out.println("链接服务器的同时,还可以做其他的事情");
}
}
//得到一个缓冲区并存入数据
String msg="hello";
ByteBuffer wrap = ByteBuffer.wrap(msg.getBytes());
//发送数据
channel.write(wrap);
}
- 服务端
public static void main(String [] args){
//ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//创建Selector
Selector selector = Selector.open();
//绑定一个端口号
serverSocketChannel.bind(new InetSocketAddress(9999));
//设置非阻塞方式
serverSocketChannel.configureBlocking(false);
//实现ServerSocketChannel注册到Selector
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true){
if (selector.select(2000)==0){
System.out.println("无人搭理");
continue;
}
//得到SelectionKey,判断通道里的事件
Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();
while (keyIterator.hasNext()){
SelectionKey key = keyIterator.next();
if (key.isAcceptable()){//客户端连接事件
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1024));
}
if (key.isReadable()){//读取客户端数据事件
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer = (ByteBuffer) key.attachment();
channel.read(buffer);
}
//手动从集合中移除key,防止重复处理
keyIterator.remove();
}
netty使用