进程:一个程序进入内存运行,即变成一条进程
线程:程序执行流的最小单元,一个标准的线程由线程ID、当前指针、寄存器集合、堆栈组成
新建状态:仅由虚拟机分配了内存,并初始化其成员变量。
就绪状态:调用了该对象的start()方法,随时可能被执行。
运行状态:线程只能从就绪状态进入运行状态。
阻塞状态:线程暂时放弃CPU使用权,直到线程进入就绪状态才有机会转到运行状态
阻塞情况分三种:等待阻塞,通过调用wait()让线程等待某工作的完成。
同步阻塞,线程获取synchronize同步锁失败(锁可能被其他线程占用),进入同步阻塞状态。
其他阻塞,调用sleep()或join()或发出I/O请求时进入阻塞状态。
死亡状态:线程执行完了、因异常退出run()方法或直接调用stop()方法(容易导致死锁,不推荐使用),该线程生命周期结束。
第一种:继承Thread类创建
步骤:1、定义Thread子类,重写run()方法
2、创建线程对象
3、调用start()启动
public class MyThread extends Thread{
public void run(){
for(int i=0;i<10;i++){
System.out.println("继承Thread,重写run");
}
}
}
public class Main{
public static void main(String[] args){
//创建并启动
MyThread t = new MyThread();
//开启
t.start();
}
}
第二种:实现Runnable接口创建线程
步骤:1、定义接口实现类,重写run()方法。
2、创建Runnanble实现类的实例,用这个实例作为Thread的target来创建Thread对象,这个Thread对象才是真正的线程对象
3、调用start()启动
public class MyThread2 implements Runnable{
public void run(){
for(int i=0;i<10;i++){
System.out.println("继承Thread,重写run");
}
}
}
public class Main{
public static void main(String[] args){
//创建接口实现类实例
MyThread2 myThread = new MyThread2();
//调用接口创建并启动线程
Thread thread = new Thread(myThread);
thread().start();
//或者new Thread(new MyThread2()).start();
}
}
创建时设置线程名称
public Thread(Runnable target,String name)
//参数target表示通过实现Runnable接口的类对象
//参数name线程名字
设置线程名称的普通方法
public final synchronized void setName(String name)
取得线程名的普通方法
public final String getName()
例:输出当前运行线程名称
//Thread.currentThread()取得jvm中运行的线程
System.out.println("当前线程"+Thread.currentThread().getName())
线程休眠是指让线程暂缓执行,等预计时间之后在恢复。sleep方法让线程运行状态转为阻塞状态。
sleep方法:
public static native void sleep(long millis) throws InterruptedException;
使用sleep:
Thread.sleep(1000); //休眠1000毫秒
线程让步是指暂停当前线程让其他线程先执行。
yield方法和sleep方法类似,不会释放锁,但yield不能控制具体交出cpu时间,yield方法不会进入阻塞状态,会转为就绪状态。
yield方法:
public static native void yield();
使用yield:
Thread.yield();
等待线程终止指的是如果主线程调用该方法就会让主线程休眠,让调用join的线程先执行。
join方法:
public final void join() throws InterruptedException{
join(0);//这是不带参数的,join还可以带参数
}
使用join:
thread1.join();
synchronnized(任意对象){
同步代码块
}
synchronized关键字可以给对象和方法加锁,使同一时刻只有一个线程执行这段代码,其他线程只能等执行完才能执行该代码块。
在访问修饰符后,返回值前加synchronized关键字
public synchronized void 方法名(){
synchronized(this){.....}
}
在使用synchronized时,可以与wait()、notify()、nitifyAll()一起使用,从而实现线程的通信。
方法 | 功能 |
---|---|
wait | 会释放占有的对象锁,当前线程进入等待池,释放cpu,而其他正等待的线程即可抢占此锁,获得锁的线程即可运行 |
sleep | 当前线程休眠一段时间,休眠期间释放cpu,不会释放锁,也就是休眠期间其他程序依然无法进入被保护的代码内部,休眠结束重新获得cpu,执行被保护的代码 |
notify | 会唤醒因为调用对象的wait()而处于等待的线程,使该线程有机会获得对象锁。调用notify后当前线程不会立即释放锁,而是继续执行当前代码,直到synchronized中的代码执行完 |
wait和notify必须在synchronized代码中调用
利用java的sockets通信API完成TCP通信过程。
步骤:1.建立tcp链接 2.发送数据包 3.关闭链接
import java.io.OutputSrea;
import java.net.Socket;
public class TestClient{
public static void main(String[] args) throws Exception{
String content="";
for(int i=1;i<=10;i++){
content = "第四轮,第"+i+"次消息";
//1.建立链接
Socket socket = new Socket("127.0.0.1",554);
//2.发送数据
OutputStrean o = socket.getOutputStream();
byte[] b = content.getBytes("GBK");
o.write(b);
//3.关闭
socket.close();
Tread.sleep(100);//线程每100豪秒后循环一次
}
}
}
public void readXmlByDom() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
//读取文件
String xmlName = System.getProperty("user.id")+"\\data\\Students.xml";
//获取xml的dom模型
Document doc = builder.parse(xmlName);
//去掉文件中的空白
doc.normalize();
//获取到class节点下的所有子节点列表
NodeList student = doc.getElementByTagName("student");
//通过item(0)获取到第一个student节点
Element s1 = (Element)student.item(0);
//输出该节点的属性sequence的值
System.out.println(s1.getAttribule("sequence"));
//输出指定节点值
Node id1=s1.getElementsByTagName("id").item(0);
System.out.println(id1.getFirstChild().getNodeValue());
System.out.println("================");
//遍历所有student节点下所有子节点和对应的值
for(int i=0; i<students.getLength(); i++){
Element son = (Element)student.item(i);;
for(Node node=son.getFirstChild(); node!=null; node=node.getNextSibling()){
if(node.getNodeType()==node.ELEMENT_NODE){
String name = node.getNodeName();
String value = node.getFirstChild().getNodeValue();
System.out.println(name+":"+value);
}
}
System.out.println("=============================");
}
}
public void addXml(){
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setIgnoringElementContentWhitespace(false);
String xmlName = System.getProperty("user.dir")+"\\data\\Stydents.xml";
try{
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlName);
Element root = doc.getDocumentElement();
//创建一个节点,并设置属性id=01
Element root = doc.createElement("son");
son.setAttribute("id","01");
//为son创建一个子节点,命名为name
Element name = doc.createElement("name");
name.setTextContent("儿子");
//将该节点name添加到父节点son中
son.appendChild(name);
//为son创建一个子节点,命名为age
Element age = doc.createElement("name");
age.setTextContent("10");
son.appendChild(son);
//将子节点添加到文档中
root.appendChild(son);
//保存该xml的文件内容
TransformerFactory factory = TransformerFactory.newInstance();
Transformer former = factory.newTransformer();
former.transform(new DOMSource(doc), new StreamResult(new File(xmlName)));
}catch(Exception e){
e.printStackTrace();
}
}