黑马程序员-----多线程

来源:互联网 发布:高性能服务器编程 pdf 编辑:程序博客网 时间:2024/06/01 10:33

------- 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.87ServerSocket 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,在实际操作中,打开俩个程序,看到的都是同步运行的,实际上是交替运行的,只不过时间过短,让人错以为是同步执行。

0 0