一、数据库mysql
1. show databases;//查看数据库名
2. create/drop databse basename创建/删除数据库
3. use databasename;
4. show tables;
5. desc 表名
6.sql语言基础
DML:数据操作语言insert update delete
DDL:数据定义语言create alter drop truncate
DCL:数据控制语言grant revoke
create user 'zz'@'%';创建用户
drop user 'dd';删除用户
GRANT privilegesON databasename.tablename TO 'username'@'host'
REVOKE privilegeON databasename.tablename FROM 'username'@'host';
附表:在MySQL中的操作权限
set password for'zz'@'localhost'=password('1169');设置用户密码
常见的数据库对象:table表view视图 constraint约束 index索引 function函数 procedure存储过程trigger触发器
Mysql支持的数据类型:int varchar time date text…
表:
表的基本操作(create alter(add modify drop) drop truncate)
create:create table student (sno int ,snamevarchar(20));//建立表
Alter :alter table student add xx int; //修改表(增加列)
Alter :alter tablestudent drop column xx ; //修改表(删除列)
Alter :alter tablestudent modify xx vatchar; //修改表的数据类型
alter table scomodify sno int first;//l修改列的位置
alter table scomodify sno int after yy; 修改列的位置
Drop:drop table student;//删除表
Truncate :truncatestudent;清除全部数据
表的约束(约束信息在information_schema里面的table_constraints):
not nulll/unique/primarykey/foreign key/check
alter tablestudent modify sno int not null primary key default '1500730142' unique;非空主键默认值唯一
alter table xxmodify sno int;删除not null
create table xx (name varchar(10),noint,unique(name) );//添加唯一性
alter table student add constraint uq_snounique(sno);//t添加唯一性
alter table student drop index sno;删除唯一约束
create table xx(sno int,sname varchar(20),constraint yueshu primary key(sno));//添加主键
alter tablestudent add constraint pk_sno primary key(sno);//添加主键
alter table xxdrop primary key;删除主键
alter table scoadd constraint fk_sno foreign key(sno) references student(sno);//添加外键
alter table scodrop constraint fk_sno;//删除外键
索引information_schema的statictics里面):
create indexnamescore on student(sname);
drop indexnamescore on student;
视图:
create or replaceview name_sno as select * from student;
drop viewname_sno;
数据的操作:
插入:mysql>insert into student values
-> (1500730131,'zylg1'),(1500730132,'zylg2');
更新:mysql>update student set
-> sno=1500730133
-> where sname='zylg1';
删除:mysql>delete from student
-> where sno=1500730133;
查询:
句式(select from where group by having order by )
消除重复元素distinct
Where 里面的用词
(比较运算)>、=、<、<=、>=、<>(!=)
(逻辑+is null)and/or/not/isnull
(设范围+in)between and/in
(匹配)like
例子: select * from student where student.Snolike '%301%';
select * from student where student.Snolike '%301%' order by Sno asc ;
聚合查询
函数有sum count avg只有在having里面使用
Where是对元组进行过滤,having对分组进行过滤
集合运算
Union except intersect(SQLserver不支持)
存在量词
Exists
sql函数:
mysql> selectchar_length(Sname) as '名字的长度' from student;
sin() curdate() curtime() md5()
ifnull(i1,i2):i1=null则返回i2
nullif(i1,i2):i1==i2return null;else return i1;
if(i1,i2,i3):i1?i2:i3
isnull(i1)
case value whenvalue1 then result1 when value2 thenresult2 …else resultx end;
max() min() sum()count() avg()
JDBC的典型用法:
DriverManager类的Connection getconnection(url,user,pass)
Connnection: Createstament()得到一个statemnet对象
Preparestatement(sql)得到一个预编译对象
Setsavepoint(name)创建一个保存点
SettransactionIsolation(intlevel)设置隔离级别
Rollback(savepoint)回个事务到保存点
Setautocommit(boolean)是否自动提交
Commit()提交事务
Statement:executeQuery(sql)返回查询结果resultset对象
ExecuteUpdate(sql)更新数据
Execute(sql)
Resultset:absolute(row)移动到某行
Beforefirst()移动到第一行之前
First()
Previous()前一行
Next()下一行
Last()最后一行
packagewww.zylg.com;
import java.awt.BorderLayout;
importjava.awt.Font;
importjava.awt.event.KeyAdapter;
importjava.awt.event.KeyEvent;
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.ResultSet;
importjava.sql.Statement;
importjava.util.LinkedList;
importjavax.swing.JButton;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JOptionPane;
importjavax.swing.JPanel;
importjavax.swing.JPasswordField;
importjavax.swing.JScrollPane;
importjavax.swing.JTable;
importjavax.swing.JTextArea;
importjavax.swing.JTextField;
importjavax.swing.table.DefaultTableCellRenderer;
importjavax.swing.table.DefaultTableModel;
importjavax.swing.text.Document;
importjavax.swing.undo.UndoableEdit;
/*
* 显示数据库的表的值,执行的查询语句
* 用okbt接收传入数据,让initparam()初始化数据
* init()初始化程序然后调用connnectsql(),dispalysqsl()对tablemodel的数据进行初始化
* 最后显示表格
*
*/
public classfind//显示数据库的表
{
private Stringdriver,url,user,pass,sql;
JTextFieldurltx=new JTextField(30),usertx=new JTextField(24);
JPasswordFieldpasstx=new JPasswordField(20);
JTextAreasqltx=new JTextArea(5,80);
JButton okbt=newJButton("OK");
Statement stmt;
JFrame mainWin=newJFrame("数据库的查看");
// public voidinitParam(String paramFile) throws Exception//load parameter file
// {
// Propertiespros=new Properties();
// pros.load(newFileInputStream(paramFile));
// driver=pros.getProperty("driver");
// url=pros.getProperty("url");
// user=pros.getProperty("user");
// pass=pros.getProperty("pass");
// }
public voidinitParm()
{
url=urltx.getText();
user=usertx.getText();
pass=passtx.getText();
sql=sqltx.getText();
}
public Connectionconnectsql() throws Exception// connect sqldb
{
// initParam("mysql.ini");
Class.forName("com.mysql.jdbc.Driver");
initParm();
Connectioncon=DriverManager.getConnection(url,user,pass);
return con;
}
public void init()throws Exception
{
urltx.setText("jdbc:mysql://125.217.37.200/studentdatabase?useSSL=false");
usertx.setText("zz");
passtx.setText("1169");
sqltx.setText("select* from student");
JLabelurllb=new JLabel("URL:"),userlb=newJLabel("USER:"),passlb=new JLabel("passeord"),sqllb=newJLabel("SQL:");
JPanel jp=newJPanel();
jp.add(urllb);jp.add(urltx);jp.add(userlb);jp.add(usertx);jp.add(passlb);
jp.add(passtx);jp.add(sqllb);jp.add(newJScrollPane(sqltx));jp.add(okbt);
mainWin.add(jp,BorderLayout.NORTH);
DefaultTableModeltablemodel=new DefaultTableModel();
JTabletable=new JTable(tablemodel);
table.setRowHeight(30);
DefaultTableCellRendererr=new DefaultTableCellRenderer();
r.setHorizontalAlignment(JLabel.CENTER);
table.setDefaultRenderer(Object.class,r);
table.setFont(newFont("宋体", Font.BOLD, 14));
okbt.addActionListener(e->{
initParm();
try
{
Connectioncon=connectsql();
stmt= (Statement) con.createStatement();
Stringbool=sql.substring(0,4);
if(bool.contains("sho")||bool.contains("sel")||bool.contains("des"))
{
displaysql(stmt,tablemodel);
}
else
{
modifysql(sql);JOptionPane.showMessageDialog(mainWin,"succeed!");
}
}
catch(Exceptione1)
{
JOptionPane.showMessageDialog(mainWin,"youhave eror");
// e1.printStackTrace();
}
});
//============撤销监听事件(懒得写sql语句而已)=====================
Document doc=sqltx.getDocument();
LinkedList<UndoableEdit>undoList = new LinkedList<>();
doc.addUndoableEditListener(e-> {
UndoableEditedit = e.getEdit();
if(edit.canUndo() && undoList.size() < 30)
{
undoList.add(edit);
}
elseif (edit.canUndo() && undoList.size() >= 30)
{
undoList.pop();
undoList.add(edit);
}
});
sqltx.addKeyListener(newKeyAdapter()
{
publicvoid keyTyped(KeyEvent e) // ②
{
if(e.getKeyChar() == 26)
{
if(undoList.size() > 0)
{
undoList.removeLast().undo();
}
}
}
});
mainWin.setResizable(false);
mainWin.add(newJScrollPane(table));
mainWin.setBounds(300,100,1000,700);;
mainWin.setVisible(true);
}
private void displaysql(Statementstmt,DefaultTableModel tablemodel) throws Exception
{
ResultSetrs=stmt.executeQuery(sql);
intcolumnnum=rs.getMetaData().getColumnCount();//得到列数
rs.last();
intrownum=rs.getRow();//得到行数
rs.first();
Stringcolumnname[]=new String[columnnum] ;
Stringdata[][]=new String[rownum][columnnum];
for(inti=1;i<=columnnum;i++){columnname[i-1]=rs.getMetaData().getColumnName(i);}
int j=0;
do
{
for(inti=0;i<columnnum;i++){data[j][i]=rs.getString(i+1);}
j++;
}while(rs.next());
tablemodel.setDataVector(data,columnname);
}
private voidmodifysql(String asql) throws Exception
{
stmt.executeUpdate(asql);
}
public static voidmain(String[] args) throws Exception
{
newfind().init();
}
}
2.stmt.execute(sql);可执行任何sql语句
3.try(PreparedStatement stmt=(PreparedStatement)con.prepareStatement("insertinto student(Sno,Sname,Ssex) values(?,?,'1')");)
{
for (int i = 0; i < 100 ; i++ )
{
stmt.setString(1, ""+(1000+i));
stmt.setString(2, "zxw");
stmt.executeUpdate();
}
}
/*
* 查看图片
* ResultSetrs = query.executeQuery())
{
if (rs.next())
{
// 取出Blob列
Blob imgBlob = rs.getBlob(1);
// 取出Blob列里的数据
ImageIcon icon=newImageIcon(imgBlob.getBytes(1L
,(int)imgBlob.length()));
imageLabel.setIcon(icon);
}
}
*/
public class find
{
JFrame mainWin = new JFrame("上传文件");
JLabel label = new JLabel("请选择:");
JTextField fieldtx = new JTextField(40);
JFileChooser chooser = new JFileChooser(".");
JButton choosefilebt = new JButton("...");
JButton uploadbt = new JButton("上传");
JTextField state=new JTextField(40);
myfilter filter = new myfilter();
String url, user, passwd, driver;
Connection conn;
PreparedStatement insert;
void connectsql(String filename) throws Exception
{
Properties pros = new Properties();
pros.load(new FileInputStream(filename));
driver = pros.getProperty("driver");
url = pros.getProperty("url");
user = pros.getProperty("user");
passwd = pros.getProperty("pass");
Class.forName(driver);
conn = DriverManager.getConnection(url, user, passwd);
insert = conn.prepareStatement("insert into img_table" + " values(null,?,?)", Statement.RETURN_GENERATED_KEYS);
}
public void init() throws Exception
{
connectsql("mysql.ini");
// -------初始化文件选择器--------
filter.addExtension("jpg");
filter.addExtension("jpeg");
filter.addExtension("gif");
filter.addExtension("png");
filter.setdesc("图片文件(*.jpg,*.jpeg,*.gif,*.png)");
chooser.addChoosableFileFilter(filter);
chooser.setAcceptAllFileFilterUsed(false);
JPanel jp = new JPanel();
state.setEditable(false);
jp.add(label);
jp.add(fieldtx);
jp.add(choosefilebt);
jp.add(uploadbt);
jp.add(state);
choosefilebt.addActionListener(e ->
{
int result = chooser.showDialog(mainWin, "浏览图片文件上传");
if (result == JFileChooser.APPROVE_OPTION)
{
fieldtx.setText(chooser.getSelectedFile().getPath());
}
});
uploadbt.addActionListener(e->{
if(fieldtx.getText().length()>0)
{
upload(fieldtx.getText());
state.setText(fieldtx.getText()+"\t 上传成功\n");
fieldtx.setText("");
}
});
mainWin.add(jp);
mainWin.setBounds(200, 200, 700, 200);
mainWin.setVisible(true);
}
// ---------将指定图片放入数据库---------
public void upload(String fileName)
{
String imageName = fileName.substring(fileName.lastIndexOf('\\') + 1, fileName.lastIndexOf('.'));
File f = new File(fileName);
try (InputStream is = new FileInputStream(f))
{
insert.setString(1, imageName);
insert.setBinaryStream(2, is, (int) f.length());
insert.executeUpdate();
} catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception
{
new find().init();
}
// define file filter
class myfilter extends FileFilter
{
private String desc = "";
private ArrayList<String> extensions = new ArrayList<>();
public void addExtension(String extension)
{
if (!extension.startsWith("."))
{
extension = "." + extension;
extensions.add(extension.toLowerCase());
}
}
public void setdesc(String aDescription)
{
desc = aDescription;
}
@Override
public boolean accept(File f)
{
if (f.isDirectory())
return true;
String name = f.getName().toLowerCase();
for (String extension : extensions)
{
if (name.endsWith(extension))
{
return true;
}
}
return false;
}
@Override
public String getDescription()
{
// TODO Auto-generated method stub
return desc;
}
}
}
·
输入和输出
1. file类
1.1访问文件和目录
Getname()
getpath()
getabsolutefile()
getparent()
renameTo()
exists()
canwrite()
canread()
isfile()
isdirectory()
isabsolute()
lastmodify()
length()
createnewfile()
delete()
createtempfile()
mkdir()
list()列出所有子文件名和路径名返回string
listfile()返回file
listroot()
public class find
{
public static void main(String[] args)
throws IOException
{
File file = new File(".");
System.out.println(file.getName());
System.out.println(file.getParent());
System.out.println(file.getAbsoluteFile());//得到绝对路径
System.out.println(file.getAbsoluteFile().getParent());
File tmpFile = File.createTempFile("aaa", ".txt", file);//新建临时文件
tmpFile.deleteOnExit();//退出的时候删除临时文件
File newFile = new File("xa.txt");
newFile.createNewFile();//在磁盘新建文件
System.out.println("newFile对象是否存在:" + newFile.exists());
if(newFile.mkdir()){System.out.println("create new directory");}
String[] fileList = file.list((dir,name)->name.endsWith(".java")||newFile(name).isDirectory());
System.out.println("====当前路径下所有文件和路径如下====");
for (String fileName : fileList)
{
System.out.println(fileName);
}
// listRoots()静态方法列出所有的磁盘根路径。
File[] roots = File.listRoots();
System.out.println("====系统所有根路径如下====");
for (File root : roots)
{
System.out.println(root);
}
}
}
流
输出流基类outputstream writer 使用write(byte[],intoffint length)或者char[]读取出来
输入流reader inputstream 使用read(byte[],int offintlength)或者char[]读取出来
public class find
{
public static void main(String[] args) throws Exception
{
File file=new File(".");
FileReader infile=new FileReader
(file.getAbsoluteFile().getParent()+"/src/www/zylg/com/find.java");
FileWriter outfile=new FileWriter("out2.txt");
char[] buff=new char[1024];
int hasread=0;
while((hasread=infile.read(buff))>0)
{
System.out.println(new String(buff,0,hasread));
outfile.write(new String(buff,0,hasread));
}
outfile.close();
infile.close();
}
}
转换流
Inputstereamreader outputstreamreader将字节流转换成字符流
回退流
// 创建一个PushbackReader对象,指定推回缓冲区的长度为64
PushbackReader pr = new PushbackReader(new FileReader(file.getAbsoluteFile().getParent()+
"/src/www/zylg/com/find.java") , 64))
pr.unread((lastContent+ content).toCharArray());
pr.read(buf, 0 , targetIndex);
重定向
try(
// 一次性创建PrintStream输出流
PrintStream ps = new PrintStream(new FileOutputStream("out.txt")))
{
// 将标准输出重定向到ps输出流
System.setOut(ps);
// 向标准输出输出一个字符串
System.out.println("普通字符串");
// 向标准输出输出一个对象
System.out.println(new RedirectOut());
}
public class find
{
public static void main(String[] args)
{
try(
FileInputStream fis = new FileInputStream("out.txt"))
{
// 将标准输入重定向到fis输入流
System.setIn(fis);
// 使用System.in创建Scanner对象,用于获取标准输入
Scanner sc = new Scanner(System.in);
// 增加下面一行将只把回车作为分隔符
sc.useDelimiter("\n");
// 判断是否还有下一个输入项
while(sc.hasNext())
{
// 输出输入项
System.out.println("键盘输入的内容是:" + sc.next());
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
Java虚拟机获取子进程的数据的流
Geterrorstream getinputstream getoutputstream
Randomaccessfile自由访问文件
try(
//以读、写方式打开一个RandomAccessFile对象
RandomAccessFile raf = new RandomAccessFile("out.txt" , "rw"))
{
//将记录指针移动到out.txt文件的最后
raf.seek(raf.length());
raf.write("追加的内容!\r\n".getBytes());
}
对象序列化(只是接受第一次的序列化,对象序列化之后,修改对象的值,但是储存好的序列并不会再次改变)
public class find implements java.io.Serializable//序列化的声明
{
String name;
transient int age;//此变量不会被序列化
public find(String name, int age)
{
super();
this.name = name;
this.age = age;
}
public static void main(String[] args)
{
try(ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("object.txt"));)//写入文件
{
find f1=new find("zylg1", 21);
find f2=new find("zylg2", 22);
find f3=new find("zylg3", 23);
find f4=new find("zylg4", 24);
oos.writeObject(f1);
oos.writeObject(f1);
oos.writeObject(f2);
oos.writeObject(f3);
oos.writeObject(f4);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
public class find implements java.io.Serializable
{
String name;
int age;
public find(String name, int age)
{
super();
this.name = name;
this.age = age;
}
public static void main(String[] args)
{
try(ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.txt"));)//读入文件
{
find f1=(find)ois.readObject();
System.out.println(f1.name);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Nio
Buffer类似于容器,除boolean外基本数据类型都有buffer,intbuffer…
Int capacity() 返回容量的大小
Int limit()返回limit的位置
Buffer limit(int)重新设置limit的位置
Int position()返回position的位置
Buffer position(int)方重新设置position的位置
Buffer mark()在0到position之间做mark
Int remaining()返回当前位置和limit之间的元素个数
Boolean hasremaining()判断position和limit之间是否还有空间
Buffer reset()将position的位置转到mark的地方
Buffer rewind()将position的位置设置为0
Put()
Get()
public static void main(String[] args)
{
// 创建Buffer
CharBuffer buff = CharBuffer.allocate(8); // create 8 capacity
System.out.println("capacity: " +buff.capacity());
System.out.println("limit: " + buff.limit());
System.out.println("position: " + buff.position());
// 放入元素
buff.put('a');
buff.put('b');
buff.put('c');
System.out.println("加入三个元素后,position = "
+ buff.position());
// 调用flip()方法
buff.flip(); // ③
System.out.println("执行flip()后,limit = " + buff.limit());
System.out.println("position = " + buff.position());
// 取出第一个元素
System.out.println("第一个元素(position=0):" + buff.get()); // ④
System.out.println("取出一个元素后,position = "
+ buff.position());
// 调用clear方法
buff.clear();
System.out.println("执行clear()后,limit = " + buff.limit());
System.out.println("执行clear()后,position = "
+ buff.position());
System.out.println("执行clear()后,缓冲区内容并没有被清除:"
+ "第三个元素为:" + buff.get(2)); // ⑥
System.out.println("执行绝对读取后,position = "
+ buff.position());
}
Channel中的数据程序不可以读和写,与buffer相互使用,转化为buffer才行,此外各种流的getchannel可以返回channel的类型,在channel中常用的三个方法map() /read()/write()
public class find
{
public static void main(String[] args)
{
File f=new File("out2.txt");
try(FileChannel inchannel=new FileInputStream(f).getChannel();
FileChannel outchannel=new FileOutputStream("channel.txt").getChannel())
{
MappedByteBuffer buffer=inchannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
outchannel.write(buffer);//写入得是buffer类型的数据
buffer.clear();//复原position和limit的位置
Charset charset=Charset.forName("GBK");//使用gbk的字符集创建解码器
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode(buffer);
System.out.println(charBuffer);
}
catch(Exception e)
{}
}
}
字符集charset,gbk,utf-8,…
public static void main(String[] args)
{
// 获取Java支持的全部字符集
SortedMap<String,Charset> map = Charset.availableCharsets();
for (String alias : map.keySet())
{
// 输出字符集的别名和对应的Charset对象
System.out.println(alias + "----->"
+ map.get(alias));
}
}
public static void main(String[] args)
throws Exception
{
// 创建简体中文对应的Charset
Charset cn = Charset.forName("GBK");
// 获取cn对象对应的编码器和解码器
CharsetEncoder cnEncoder = cn.newEncoder();
CharsetDecoder cnDecoder = cn.newDecoder();
// 创建一个CharBuffer对象
CharBuffer cbuff = CharBuffer.allocate(8);
cbuff.put('孙');
cbuff.put('悟');
cbuff.put('空');
cbuff.flip();
// 将CharBuffer中的字符序列转换成字节序列
ByteBuffer bbuff = cnEncoder.encode(cbuff);
// 循环访问ByteBuffer中的每个字节
for (int i = 0; i < bbuff.capacity() ; i++)
{
System.out.print(bbuff.get(i) + " ");
}
// 将ByteBuffer的数据解码成字符序列
System.out.println("\n" + cnDecoder.decode(bbuff));
}
}
文件的操作
Path,files弥补了file的不足
public class find
{
public static void main(String[] args)
throws Exception
{
// 以当前路径来创建Path对象
Path path = Paths.get(".");
System.out.println("path里包含的路径数量:"
+ path.getNameCount());
System.out.println("path的根路径:" + path.getRoot());
// 获取path对应的绝对路径。
Path absolutePath = path.toAbsolutePath();
System.out.println(absolutePath);
// 获取绝对路径的根路径
System.out.println("absolutePath的根路径:"
+ absolutePath.getRoot());
// 获取绝对路径所包含的路径数量
System.out.println("absolutePath里包含的路径数量:"
+ absolutePath.getNameCount());
System.out.println(absolutePath.getName(3));
// 以多个String来构建Path对象
Path path2 = Paths.get("g:" , "publish" , "codes");
System.out.println(path2);
}
}
Files提供一系列文件的工具
public static void main(String[] args)
throws Exception
{
// 复制文件
Files.copy(Paths.get("out2.txt")
, newFileOutputStream("a.txt"));
// 判断FilesTest.java文件是否为隐藏文件
System.out.println("FilesTest.java是否为隐藏文件:"
+ Files.isHidden(Paths.get("out2.txt")));
// 一次性读取FilesTest.java文件的所有行
List<String> lines = Files.readAllLines(Paths
.get("out2.txt"),Charset.forName("gbk"));
System.out.println(lines);
// 判断指定文件的大小
System.out.println("out2.txt的大小为:"
+ Files.size(Paths.get("out2.txt")));
List<String> poem = new ArrayList<>();
poem.add("水晶潭底银鱼跃");
poem.add("清徐风中碧竿横");
// 直接将多个字符串内容写入指定文件中
Files.write(Paths.get("pome.txt"), poem
, Charset.forName("gbk"));
// 使用Java 8新增的Stream API列出当前目录下所有文件和子目录
Files.list(Paths.get(".")).forEach(path -> System.out.println(path));
// 使用Java 8新增的Stream API读取文件内容
Files.lines(Paths.get("out2.txt") , Charset.forName("gbk"))
.forEach(line -> System.out.println(line));
FileStore cStore = Files.getFileStore(Paths.get("C:"));
// 判断C盘的总空间,可用空间
System.out.println("C:共有空间:" + cStore.getTotalSpace());
System.out.println("C:可用空间:" + cStore.getUsableSpace());
}
多线程
1.线程的创建
Thread创建的线程,把run作为执行体,创建thread对象就是创建了线程,start()启动线程 new mythread().start();
Runnable接口也可以创建线程 new Thread(new myrunnable(),”新线程”).strat();
futureTask作为callable的接口的实现类,可以创建有返回值的线程
FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>)()-> {
int i = 0;
for ( ; i < 100 ; i++ )
{
System.out.println(Thread.currentThread().getName()
+ " 的循环变量i的值:" + i);
}
// call()方法可以有返回值
return i;
});
new Thread(task , "zylg").start();
System.out.println("子线程的返回值:" + task.get());
2. 线程的状态
Sleep()让线程休眠
public class find implements Runnable
{
public static void main(String[] args) throws InterruptedException
{
Thread f1=new Thread(new find(),"my thread");
f1.start();
}
@Override
public void run()
{
for(int i=0;i<20;i++)
{
System.out.println("now Time is :"+new Date());
try
{
Thread.sleep(1000);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Suspend()挂起
Start()运行
Stop()强制停止
Notify()等待通知
Join()加入线程,必须等待加入的线程执行完再继续上一个线程
package www.zylg.com;
public class find implements Runnable
{
public static void main(String[] args) throws InterruptedException
{
Thread f1=new Thread(new find(),"my thread");
for(int i=0;i<10;i++)
{
System.out.println("main thread "+i);
if(i==2){f1.start();f1.join();}
}
}
@Override
public void run()
{
for(int i=0;i<20;i++)
{
System.out.println("jion thread"+i);
}
}
}
Setdaemon(true)设置为后台的进程,当前台的进程都结束了,他会自动结束
Yield线程的让步,只有线程的优先级高于或者等于,让步才可能成功
package www.zylg.com;
/*
*优先级低的让优先级高的才会成功
*/
public class find extends Thread
{
public find(String name)
{
super(name);
}
public static void main(String[] args) throws InterruptedException
{
Thread t1=new find("advanced thread");
Thread t2=new find("low thread");
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t2.start();
t1.start();
}
@Override
public void run()
{
for(int i=0;i<20;i++)
{
System.out.println(getName()+i);
if(i==5){Thread.yield();}
}
}
}
线程的同步快
package www.zylg.com;
/*
*线程的同步块的使用
*/
public class find extends Thread
{
Acount acount;
double drawcount;
public find(String name, Acount act, double drawcount) {
super(name);
this.acount = act;
this.drawcount = drawcount;
}
@Override
public void run()
{
synchronized (acount)//使用啊acount对象作为同步监视器
{
if(acount.getBalance() - drawcount >= 0)
{
System.out.println(getName()+ "trans succeed。" + drawcount + "\tremaining: " + acount.getBalance());
acount.setBalance((acount.getBalance()- drawcount));
} else
{
System.out.println(getName()+ "trans defeat。" +"\tremaining: " + acount.getBalance());
}
}
}
public static void main(String[] args) throws InterruptedException
{
Acount acct = new Acount("15007301", 1000);
new find("甲", acct, 800).start();
new find("乙", acct, 800).start();
new find("丙", acct, 800).start();
}
}
class Acount// 账户,有账户编号和账户余额
{
String acountno;
double balance;
public Acount(String acountno, double balance) {
super();
this.acountno = acountno;
this.balance = balance;
}
public double getBalance()
{
return balance;
}
public void setBalance(double balance)
{
this.balance = balance;
}
public String getAcountno()
{
return acountno;
}
public void setAcountno(String acountno)
{
this.acountno = acountno;
}
}
当然,还有同步方法,在方法类型前面加上synchronized,同步监视的对象为this
释放同步监视器break或者return或者出现error
public synchronized void drawmoney(String str, double drawcount)
{
if ( getBalance()- drawcount >= 0)
{
System.out.println(str+"trans succeed。" + drawcount+ "\tremaining: " + getBalance());
setBalance((getBalance() -drawcount));
} else
{
System.out.println(str+"trans defeat。" +"\tremaining: " + getBalance());
}
}
锁之可重入锁
ReentrantLocklock=new ReentrantLock();
public void drawmoney(String str, double drawcount)
{
lock.lock();
if ( getBalance()- drawcount >= 0)
{
System.out.println(str+ "trans succeed。" + drawcount + "\tremaining: " + getBalance());
setBalance((getBalance() -drawcount));
} else
{
System.out.println(str+ "trans defeat。" +"\tremaining: " + getBalance());
}
lock.unlock();
}
线程的通信
Wait()和notify()或者notifyall()的使用,这是必须存在同步块的时候使用
如果其他则是await()和signalall()
线程组
Thread(threadgroup ,target,name)
Threadgroup(threadgroup parent, name)
Intactivecount()线程组的活动数目
Interrup()中断线程组线程
Isdaemon()
Setdaemon()
Setmaxpriority()
class MyThread extends Thread
{
// 提供指定线程名的构造器
public MyThread(String name)
{
super(name);
}
// 提供指定线程名、线程组的构造器
public MyThread(ThreadGroup group , String name)
{
super(group, name);
}
public void run()
{
for (int i = 0; i < 20 ; i++ )
{
System.out.println(getName() + " 线程的i变量" + i);
}
}
}
public class ThreadGroupTest
{
public static void main(String[] args)
{
// 获取主线程所在的线程组,这是所有线程默认的线程组
ThreadGroup mainGroup = Thread.currentThread().getThreadGroup();
System.out.println("主线程组的名字:"
+ mainGroup.getName());
System.out.println("主线程组是否是后台线程组:"
+ mainGroup.isDaemon());
new MyThread("主线程组的线程").start();
ThreadGroup tg = new ThreadGroup("新线程组");
tg.setDaemon(true);
System.out.println("tg线程组是否是后台线程组:"
+ tg.isDaemon());
MyThread tt = new MyThread(tg , "tg组的线程甲");
tt.start();
new MyThread(tg , "tg组的线程乙").start();
}
}
线程池
Excuteors工厂类包含的线程创建方法
Newcachedthreadpool()创建具有缓存功能的线程池
Newfixedthreadpool(int)创建具有可重用具有固定数目的线程池
Newscheduledthreadpool(int)指定数目的线程池。,可以在指定延迟后执行
Newsinglethreadscheduledexcutor()创建单个线程的线程池,指定延迟执行
public class find
{
public static void main(String[] args)
{
ExecutorService pool=Executors.newFixedThreadPool(6);
Runnable target=()->{
for(int i=0;i<10;i++)
{
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
};
pool.submit(target);
pool.submit(target);
pool.shutdown();
}
}
线程的迸发
package www.zylg.com;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit;
class PrintTask extends RecursiveAction
{
// 每个“小任务”只最多只打印50个数
private static final int THRESHOLD = 50;
private int start;
private int end;
// 打印从start到end的任务
public PrintTask(int start, int end)
{
this.start = start;
this.end = end;
}
@Override
protected void compute()
{
// 当end与start之间的差小于THRESHOLD时,开始打印
if(end - start < THRESHOLD)
{
for (int i = start ; i < end ; i++ )
{
System.out.println(Thread.currentThread().getName()
+ "的i值:" + i);
}
}
else
{
// 如果当end与start之间的差大于THRESHOLD时,即要打印的数超过50个
// 将大任务分解成两个小任务。
int middle = (start + end) / 2;
PrintTask left = new PrintTask(start, middle);
PrintTask right = new PrintTask(middle, end);
// 并行执行两个“小任务”
left.fork();
right.fork();
}
}
}
public class find
{
public static void main(String[] args)
throws Exception
{
ForkJoinPool pool = new ForkJoinPool();
// 提交可分解的PrintTask任务
pool.submit(new PrintTask(0 , 300));
pool.awaitTermination(2, TimeUnit.SECONDS);
// 关闭线程池
pool.shutdown();
}
}
线程相关类
网络编程
InetAddress代表IP地址类,无构造器分为ipv4和ipv6
Getbyname(hostname)
Getbyaddress(byte[]addr)
Stringgetcanonicalhostname()获取此ip地址的全限定域名
Stringgethostaddress()
Stringgethostname()
url类
String keyword=URLDecoder.decode("%CE%D2","gbk");
String str=URLEncoder.encode("我好像在哪里见过你","gbk");
String getfile()获取该url的资源名
Stringgethost()获取该url的主机名
Stringgetpath()获取路径部分
Int getport()获取端口号
Stringgetprotocol获取url的协议名称
Stringgetquery()获取该url的查询字符串部分
URLconnectionopenconnection()
Inputstreamopenstream()读取url资源的inputstream
packagewww.zylg.com;
importjava.io.InputStream;
importjava.io.RandomAccessFile;
importjava.net.HttpURLConnection;
import java.net.URL;
/*
* 定义一个下载的线程类,之后用下载单元的类去管理下载线程,实现了多线程下载
*/
public class find
{
public static void main(String[] args) throws Exception
{
DownUtil downUtil=new DownUtil("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&"
+ "sec=1509182049986&di=2c3dba800670f02fcb5938c25b93c3f8&imgtype=0&src=http%3A%2F%2Fp1.gex"
+ "ing.com%2FG1%2FM00%2F1C%2F83%2FrBACE1a-AvuxOU2SAApfvJ7Qj9o118.jpg", "小黄人.jpg", 1);
downUtil.download();
new Thread(() -> {
while(downUtil.getCompleteRate() < 1)
{
// 每隔0.1秒查询一次任务的完成进度,
// GUI程序中可根据该进度来绘制进度条
System.out.println("已完成:"
+ downUtil.getCompleteRate());
try
{
Thread.sleep(1000);
}
catch (Exception ex){}
}
}).start();
}
static class DownUtil
{
//========定义下载的线程======================
private class DownTread extends Thread
{
private int startPos;//线程的下载开始位置
private int filesize;//线程下载的文件大小
private RandomAccessFile file;//线程的下载保存文件
private int lenght;//获取下载完成的大小,完成百分比用到
public DownTread(int startPos, int filesize, RandomAccessFile file)
{
super();
this.startPos = startPos;
this.filesize = filesize;
this.file = file;
}
@Override
public void run()
{
try
{
URL url=new URL(downpath);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg,image/pjpeg, "
+ "application/x-shockwave-flash,application/xaml+xml, "
+ "application/vnd.ms-xpsdocument,application/x-ms-xbap, "
+ "application/x-ms-application,application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint,application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
InputStream inStream = conn.getInputStream();
// 跳过startPos个字节,表明该线程只下载自己负责哪部分文件。
inStream.skip(this.startPos);
byte[] buffer=newbyte[1024];
int hasRead=0;
while(lenght<filesize&&(hasRead=inStream.read(buffer))!=-1)
{
file.write(buffer,0,hasRead);
lenght+=hasRead;
}
file.close();
inStream.close();
}catch (Exception e)
{
e.printStackTrace();
}
}
}
private String downpath;//定义下载资源的路径
private String savepath;//定义保存路径
private int threadnum;//使用的线程数量
private DownTread[] threads;//下载的线程组
private int filesize;
public DownUtil(String path, String targetFile, int threadNum)
{
downpath = path;
threadnum=threadNum;
savepath=targetFile;
threads=new DownTread[threadNum];
}
//============开始下载=====================
public void download() throws Exception
{
URL url=new URL(downpath);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg,image/pjpeg, "
+ "application/x-shockwave-flash,application/xaml+xml, "
+ "application/vnd.ms-xpsdocument,application/x-ms-xbap, "
+ "application/x-ms-application,application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint,application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Connection", "Keep-Alive");
filesize=conn.getContentLength();
conn.disconnect();
//==========创建相同大小的文件进行下载的储存======================
int currentPartSize =filesize / threadnum + 1;
RandomAccessFile file = newRandomAccessFile(savepath, "rw");
file.setLength(filesize);
file.close();
for (int i = 0; i <threadnum; i++)//启动线程下载
{
int startPos = i *currentPartSize;
RandomAccessFile currentPart = newRandomAccessFile(savepath,"rw");
currentPart.seek(startPos);
threads[i] = newDownTread(startPos, currentPartSize,currentPart);
threads[i].start();
}
}
// 获取下载的完成百分比
public double getCompleteRate()
{
// 统计多条线程已经下载的总大小
int sumSize = 0;
for (int i = 0; i < threadnum; i++)
{
sumSize += threads[i].lenght;
}
// 返回已经完成的百分比
return sumSize * 1.0 / filesize;
}
}
}
URLpermission工具类用于管理httpurlconnection的权限问题,使用post的方式的时候需要
Setallowuserinteraction()
Setdoinput()设置请求字段的值
Setdooutput()设置请求字段的值
Setmodifiedsince()
Setusercaches()
Setrequestproperty(key,value)设置请求字段的key的值为values
Addrequestpropwrty(key,value)
Objectgetcontent()获取urlconnection的内容
String getheadfield(Stringname)获得指定字段头的值
Getinputstraem()获得对应的输入流,用于获取urlconnection响应的内容
Getoutputstream()获得对应的输出流
Getcontentencoding()
Getcontenetype()
Getcontentlength
Getdate()
Getexpiration()
Getlastmodified()
public static String sendPost(String url , String param)
{
String result = "";
try
{
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible;MSIE 6.0; Windows NT 5.1; SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
try(
// 获取URLConnection对象对应的输出流
PrintWriter out = new PrintWriter(conn.getOutputStream()))
{
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
}
try(
// 定义BufferedReader输入流来读取URL的响应
BufferedReader in = new BufferedReader(new InputStreamReader
(conn.getInputStream() , "utf-8")))
{
String line;
while ((line = in.readLine())!= null)
{
result += "\n" + line;
}
}
}
catch(Exception e)
{
System.out.println("发送POST请求出现异常!" + e);
e.printStackTrace();
}
return result;
}
Tcp网络协议编程
Serversocket
Socket accept()
Serversocket(intport,int backlog)设定端口,参数队列长度
public static void main(String [] args) throws Exception
{
ServerSocket server=new ServerSocket(9000);
while(true)
{
Socket s=server.accept();
PrintStream print=new PrintStream(s.getOutputStream());
print.println("你收到了服务器的祝福\n小伙子你好啊");
print.close();
s.close();
}
}
/*
* socket s=new socket();
* s.connect(new inetsocketaddress(host,port),time)
* s.setsotimeout()
*
* */
public class client
{
public static void main(String [] args) throws Exception, IOException
{
Socket s=new Socket("127.0.0.1", 9000);
BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream(), "gbk"));
String str;
while((str=br.readLine())!=null)
{
System.out.println(str);
}
}
}
C/s聊天室
packagewww.zylg.com;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintStream;
importjava.net.ServerSocket;
importjava.net.Socket;
importjava.util.ArrayList;
importjava.util.Collections;
importjava.util.List;
public class Server
{
public static List<Socket> socketlist=Collections.synchronizedList(new ArrayList<>());
public static void main(String [] args) throws Exception
{
ServerSocket server=new ServerSocket(9000);
while(true)
{
Socket s=server.accept();
socketlist.add(s);
new Thread(new serverthread(s)).start();
}
}
private static class serverthread implementsRunnable
{
Socket s=null;
BufferedReader br=null;
public serverthread(Socket s) throws Exception
{
super();
this.s = s;
br=newBufferedReader(new InputStreamReader(s.getInputStream(), "gbk"));
}
@Override
public void run()//每创建一个客户端线程都会输出所有的内容到该客户端
{
String content=null;
while((content=readfromclient())!=null)
{
for(Socket s1:Server.socketlist)
{
try
{
PrintStream ps=new PrintStream(s.getOutputStream());
ps.println(content);
}catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private String readfromclient()
{
try
{
return br.readLine();
} catch (Exception e)
{
Server.socketlist.remove(s);
}
return null;
}
}
}
packagewww.zylg.com;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintStream;
importjava.net.Socket;
/*
*
* */
public class client
{
public static void main(String [] args) throws Exception, IOException
{
System.out.println("c/s聊天室");
Socket s=new Socket("127.0.0.1", 9000);
new Thread(new clientthread(s)).start();
PrintStream ps=new PrintStream(s.getOutputStream());
String line=null;
BufferedReader br=newBufferedReader(new InputStreamReader(System.in));
while((line=br.readLine())!=null)
{
ps.println(line);
}
}
private static class clientthread implements Runnable
{
private Socket s;
private BufferedReader br=null;
public clientthread(Socket s) throws Exception
{
super();
this.s = s;
br=newBufferedReader(new InputStreamReader(s.getInputStream(), "gbk"));
}
@Override
public void run()
{
try
{
String content=null;
while((content=br.readLine())!=null)
{
System.out.println("client:"+content);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
Socket可半关闭的方式存取数据shutdowninput()或者shutdownouput()
c/s聊天
package www.cs.com;
public interface zylgprotocol
{
int protocol_len=2;
String MSG_ROUND = "§γ";
String USER_ROUND = "∏∑";
String LOGIN_SUCCESS = "1";
String NAME_REP = "-1";
String PRIVATE_ROUND = "★【";
String SPLIT_SIGN = "※";
}
packagewww.cs.com;
importjava.util.Collections;
importjava.util.HashMap;
importjava.util.HashSet;
importjava.util.Map;
importjava.util.Set;
public class zylgmap<K,V>
{
public Map<K, V>map=Collections.synchronizedMap(new HashMap<>());
public synchronized void removebyvalue(Objectvalue)//delete user referen value
{
for(Object key:map.keySet())
{
if(map.get(key)==value)
{
map.remove(key);
break;
}
}
}
public synchronized Set<V>valueset()//to require valueset
{
Set<V> result=new HashSet<>();
map.forEach((key,value)->{result.add(value);});
return result;
}
public synchronized K getkeybyvalue(V value)
{
for(K key:map.keySet())
{
if(map.get(key)==value||map.get(key).equals(value))return key;
}
return null;
}
public synchronized V put(K key,V value)
{
for(V val:valueset())
{
if(val.equals(value)&&val.hashCode()==value.hashCode())
{throw new RuntimeException("Map实例中不允许有重复的值");}
}
return map.put(key, value);
}
}
packagewww.cs.com;
importjava.io.BufferedReader;
importjava.io.InputStreamReader;
importjava.io.PrintStream;
importjava.net.Socket;
public class serverthread extends Thread
{
private Socket socket;
BufferedReader br=null;
PrintStream ps=null;
public serverthread(Socket socket)
{
this.socket=socket;
}
private String getrealmsg(String line)//用来得到名字或者信息,将协议的内容去掉
{
returnline.substring(zylgprotocol.protocol_len, line.length() -zylgprotocol.protocol_len);
}
public void run()
{
try
{
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
ps=newPrintStream(socket.getOutputStream());
String line=null;
while((line=br.readLine())!=null)
{
if(line.startsWith(zylgprotocol.USER_ROUND)&&line.endsWith(zylgprotocol.USER_ROUND))
{
Stringusername=getrealmsg(line);
if(zylgserver.clients.map.containsKey(username))
{
zylgserver.txa.append("theuser is repeat\n");
ps.println(zylgprotocol.NAME_REP);
}
else
{
zylgserver.txa.append("用户"+username+"登录成功\n");
ps.println(zylgprotocol.LOGIN_SUCCESS);
zylgserver.clients.put(username,ps);
}
}
elseif(line.startsWith(zylgprotocol.PRIVATE_ROUND)&&line.endsWith(zylgprotocol.PRIVATE_ROUND))
{
String usermsg=getrealmsg(line);
Stringuser=usermsg.split(zylgprotocol.SPLIT_SIGN)[0];
Stringmsg=usermsg.split(zylgprotocol.SPLIT_SIGN)[1];
zylgserver.clients.map.get(user).println(zylgserver.clients.getkeybyvalue(ps)+"悄悄对你说:"+msg);
}
else
{
String msg=getrealmsg(line);
for(PrintStreamclientps:zylgserver.clients.valueset())
{
clientps.println(zylgserver.clients.getkeybyvalue(ps)+":"+msg);
}
}
}
}
catch(Exception e)
{
zylgserver.clients.removebyvalue(ps);
try
{
if(br!=null)br.close();
if(ps!=null)ps.close();
if(socket!=null)socket.close();
}
catch(Exception e1)
{
e1.printStackTrace();
}
}
}
}
packagewww.cs.com;
importjava.io.PrintStream;
importjava.net.ServerSocket;
importjava.net.Socket;
importjavax.swing.JFrame;
importjavax.swing.JScrollPane;
importjavax.swing.JTextArea;
public class zylgserver
{
JFrame jf=new JFrame("服务器");
public static JTextArea txa=newJTextArea(7,20);
private static final int server_port = 3000;
public staticzylgmap<String,PrintStream> clients=new zylgmap<>();
public void init()
{
jf.add(new JScrollPane(txa));
jf.setBounds(200, 200, 300, 300);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
try(ServerSocket ss=newServerSocket(server_port))
{
txa.setText("服务器启动成功\n");
while(true)
{
Socket socket=ss.accept();
new serverthread(socket).start();
}
}
catch(Exception e)
{
txa.append("服务器启动失败");
}
}
public static void main(String[] args)
{
zylgserver server = new zylgserver();
server.init();
}
}
packagewww.cs.com;
importjava.io.BufferedReader;
importjava.io.IOException;
public class clientthread extends Thread
{
BufferedReader br=null;
public clientthread(BufferedReader br)
{
this.br = br;
}
public void run()
{
try
{
String line=null;
while((line=br.readLine())!=null)
{
client.txa2.append(line+"\n");
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (br != null)
{
br.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
}
packagewww.cs.com;
importjava.awt.BorderLayout;
importjava.awt.event.ActionEvent;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintStream;
importjava.net.Socket;
importjavax.swing.AbstractAction;
importjavax.swing.Action;
importjavax.swing.JButton;
importjavax.swing.JFrame;
importjavax.swing.JOptionPane;
importjavax.swing.JPanel;
importjavax.swing.JTextArea;
importjavax.swing.JTextField;
importjavax.swing.KeyStroke;
public class client
{
static JFrame jf2=newJFrame("client");
static JTextField txf2=new JTextField(20);
static JTextArea txa2=new JTextArea(7,28);
static JButton okbt=new JButton("发送");
private static final int server_port=3000;
private Socket socket;
private PrintStream ps;
private BufferedReader brserver=null;
private BufferedReader keyIn;
public void init()
{
JPanel jp=new JPanel();
jp.add(txf2);
jp.add(okbt);
jf2.add(txa2);
jf2.add(jp,BorderLayout.SOUTH);
jf2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf2.setBounds(400, 200, 400, 400);
try
{
keyIn=new BufferedReader(newInputStreamReader(System.in));
socket=newSocket("127.0.0.1", server_port);
ps=newPrintStream(socket.getOutputStream());
brserver=new BufferedReader(newInputStreamReader(socket.getInputStream()));
String tip="";
while(true)
{
Stringusername=JOptionPane.showInputDialog(tip+"输入用户名");
ps.println(zylgprotocol.USER_ROUND+username+zylgprotocol.USER_ROUND);
jf2.setTitle(username);
String result=brserver.readLine();
if(result.equals(zylgprotocol.NAME_REP)){tip="用户名重复!请重新";continue;}
if(result.equals(zylgprotocol.LOGIN_SUCCESS))break;
}
}
catch(Exception e)
{
txa2.append("请确定服务器已经启动");
closeRs();
}
Action msg=new AbstractAction()
{
@Override
public void actionPerformed(ActionEvente)
{
try
{
String line=null;
line=txf2.getText();
if(line.indexOf(":")>0&&line.startsWith("//"))
{
line=line.substring(2);
ps.println(zylgprotocol.PRIVATE_ROUND+line.split(":")[0]+zylgprotocol.SPLIT_SIGN+line.split(":")[1]+zylgprotocol.PRIVATE_ROUND);
txf2.setText("");
}
else
{
ps.println(zylgprotocol.MSG_ROUND+line+zylgprotocol.MSG_ROUND);
txf2.setText("");
}
}
catch(Exception e1)
{
txa2.append("请确定服务器已经启动\n");
closeRs();
}
}
};
okbt.addActionListener(msg);
txf2.getInputMap().put(KeyStroke.getKeyStroke('\n'),"send");
txf2.getActionMap().put("send",msg);;
new clientthread(brserver).start();
}
private void closeRs()
{
try
{
if (keyIn != null)
{
ps.close();
}
if (brserver != null)
{
ps.close();
}
if (ps != null)
{
ps.close();
}
if (socket != null)
{
keyIn.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args)
{
client cli = new client();
cli.init();
cli.jf2.setVisible(true);
}
}
非阻塞模式的网络编程,给予api的网络编程增加一个用户往往要增加一个线程,对于很多的用户,执行效率低下,因而产生了selector。非阻塞模式下的channel都应该注册到selector对象上,
Keys()方法返回在selector上注册的channel
selectKeys()返回所有可能是select()获取的需要io处理的channel对象
再一次执行select(),上一次获取的selectkey将会被删除
Intselect()监控所有注册的channel,将对应的selectkey加入selectionkey集合中,并返回channel的数量
Int selelct(timeout)可以设置超过时长timeout的操作
Intselectnow()立即返回selelct()的操作
Int wakeup()使一个未返回的select()方法立即返回
Selectablechannel,代表非阻塞io的channnel对象,可调用register()注册到selector上,改变成非阻塞模式configureblocking()