------- android培训、java培训、期待与您交流! ----------
多线程:
线程是依赖者进程存在的
进程:
正在运行的程序,是系统进行资源分配和调用的独立单位。
每一个进程都有它自己的内存空间和系统资源。
线程:
是进程中的单个顺序控制流,是一条执行路径
一个进程如果只有一条执行路径,则称为单线程程序。
一个进程如果有多条执行路径,则称为多线程程序
单进程单线程: 一个独木桥,同时只能有一个人过;多个人的时候排队,依次通过
单进程多线程:一座大桥, 同时可以有多辆汽车行驶
多进程多线程:多座大桥,每座桥上,都可以同时可以有多辆汽车行驶
如何创建一个线程呢?
想创建线程,那么要先有进程,而进程我们创建不了,由系统来创建,我们在进程的基础上,创建线程 ( Thread )
Thread类:
是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
创建线程的几种方式?
创建新执行线程有两种方法
方式1:
继承Thread线程类
1,创建一个类为 Thread类的子类
2,该子类应重写 Thread 类的 run 方法
3,创建子类对象
4,调用start()方法,启动线程
方式2;
创建一个实现 Runnable 接口的类
1,创建自定义类实现 Runnable接口
2,在自定义类重写run()方法
3,创建自定义类对象
4,创建线程对象,并把自定义类对象,作为构造方法参数使用
5,调用start()方法,启动线程
Thread类方法介绍
构造方法:
public Thread(String name)分配新的 Thread 对象
方法:
public final String getName()返回该线程的名称。
默认的线程名称为: Thread-编号, 编号从0开始
public final void setName(String name)
改变线程名称,使之与参数 name 相同
public static Thread currentThread()
返回对当前正在执行的线程对象的引用。
返回:当前执行的线程
public final int getPriority()返回线程的优先级。
public final void setPriority(int newPriority)更改线程的优先级
IllegalArgumentException - 如果优先级不在 MIN_PRIORITY 到 MAX_PRIORITY 范围内。
IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数
public static final int MAX_PRIORITY 10 最大优先级
public static final int MIN_PRIORITY 1 最小优先级
public static final int NORM_PRIORITY 5 默认优先级
public static void sleep(long millis)
throws InterruptedException在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),
public void run()
如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
Thread 的子类应该重写该方法。
public void run() {
if (target != null) {
target.run();
}
}
同步机制的实现方式:
1, 同步代码块
格式:
synchronized(锁对象) {
可能出现线程不同步问题的代码
}
这里的锁对象,可以是任何创建的对象
2, 同步方法
普通同步方法
public synchronized void method(){}
静态同步方法
public static synchronized void method(){}
满足哪些条件,会导致线程不同步?
1, 多线程环境
2,多个线程对象,操作同一个数据 (票)
3,对共享数据(票), 进行了一步以上的操作
如何解决上述问题呢?
3,对共享数据(票), 进行了一步以上的操作
通过java中的同步机制,将与票相关的操作封装起来,同一时刻,只能有一个线程对象访问,这样,该问题解决了
同步方法的锁对象 是谁?
1,同步代码块: 锁对象是任意的,但是多个线程必须使用同一把锁
2,同步方法的锁对象是 this
3,同步静态方法的锁对象是 类名.class
Ticket.class
字节码文件对象
死锁: 在同步方法、同步代码块嵌套使用的时候,可能产生的一种异常现象[无限等待]
Lock : 锁, jdk1.5
public interface Lock
实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作
方法:
void lock()获取锁。
void unlock()释放锁。
匿名内部类方式使用多线程
new Thread(){
public void run(){
code...
}
}.start();
------------
new Thread(new Runnable(){
public void run(){
code...
}
}).start();
代码
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 文件上传 服务器【多线程版本】
*/
public class Server {
public static void main(String[] args) throws IOException {
//1, 开启服务器 192.168.33.87
ServerSocket ss = new ServerSocket(12345);
while (true){
//2,等待客户端连接
final Socket s = ss.accept();
//3,开启新线程,完成与客户端数据交互
new Thread(){
public void run() {
try {
//获取到连接上的客户端IP地址
String ip = s.getInetAddress().getHostAddress();
System.out.println("已连接的客户端 :" + ip);
//4获取客户端发来的数据,写入到服务器文本文件中
//数据源
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//目的地
long time = System.currentTimeMillis();
//"1234325254431245.txt"
File filename = new File(time+".txt");
PrintWriter pw = new PrintWriter(new FileWriter(filename), true);
//读
String line = null;
while ((line = br.readLine()) != null) {
//写
pw.println(line);
}
//关闭操作文件的流
pw.close();
//5,给客户端反馈信息
PrintWriter pwClient = new PrintWriter(s.getOutputStream(), true);
pwClient.println("文件上传成功");
//6,关闭Socket流
s.close();
} catch(IOException e){
e.printStackTrace();
}
};
}.start();
}
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 多线程 文本上传 客户端代码
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//创建Socket对象
Socket s = new Socket("192.168.33.87", 12345);
//读 多线程概述.txt 写入到Socket的输出流中
//数据源
BufferedReader br = new BufferedReader(new FileReader("多线程概述.txt"));
//目的地
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
//读
String line = null;
while ((line = br.readLine())!= null) {
//写到Socket的输出流中, 传输给了服务器端
pw.println(line);
}
//关闭文件操作的流
br.close();
//告知服务器端,数据上传完毕
s.shutdownOutput();
//获取反馈信息
BufferedReader brServer = new BufferedReader(new InputStreamReader(s.getInputStream()));
String data = brServer.readLine();
System.out.println("客户端获取到的反馈信息:" + data);
//关闭Socket流
s.close();
}
}
总结
多线程可以实行并行处理,避免了某些任务长时间占用CPU,在实际操作中,打开俩个程序,看到的都是同步运行的,实际上是交替运行的,只不过时间过短,让人错以为是同步执行。