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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值