黑马程序员-java多线程


------- android培训java培训、期待与您交流! ----------

1 进程与线程

    进程是程序的一次动态执行过程,是系统进行资源分配和调度的一个独立单位。

    线程是进程执行过程中产生的执行线索,是比进程单位更小的执行单位。

2 单线程与多线程

·  单线程的程序只有一个顺序执行流,只能依次向下执行每行代码,当某行代码遇到阻塞就会停滞不前。

    多线程的程序有多条顺序执行流,当某的线程在阻塞状态时,别的线程会抢占cpu资源来运行,多线程抢占执行权是随机性的。

3 线程的创建

   线程的创建必须要通过Thread类,有两种方式,可以是自定义类来继承Thread类,也可以是自定义类来实现Runnable接口。

    1 通过继承Thread类创建线程

        步骤:1 定义类继承Thread类

                   2 重写Thread类的run方法

                   3 调用线程的start方法来启动线程

        例子

package thread;
class ThreadDemo extends Thread { // 线程的主体类
    @Override
    public void run() { // 线程的主方法
            System.out.println("通过继承Thread类方式");//输出
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
    	ThreadDemo td = new ThreadDemo() ;//新建线程对象
        td.start() ;//调用start()启动线程
    }
}


    2 通过实现Runnable接口创建线程

       步骤:1 定义类实现Runnable接口

                  2 重写Runnable接口的run方法

                  3 声明并初始化实现Runnable接口子类对象

                  4 声明Thread类对象,将实现Runnable接口对象作为实参来实例化Thread类对象

                  5 调用Thread类对象的start方法启动线程

       例子

      

class RunnableDemo implements Runnable { // 线程的主体类
    @Override
    public void run() { // 线程的主方法
            System.out.println("通过实现Runnable接口方式");//输出
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
    	RunnableDemo rd = new RunnableDemo() ;//新建实现Runnable接口对象
    	Thread t = new Thread(rd); //声明并初始化Thread类对象,把事项Runnable接口对象作为实参
        t.start() ;//调用start()启动线程
    }
}

4 实现Runnable方法比继承Thread常用原因

  1 Runnable方式避免了Thread类方式单继承的局限性,可以继承其他类

  2 Runnable方式可以使多个线程共享同一个资源文件

5 线程的生命周期

  1 New :新建状态,当用new创建一个线程,就处于新建状态

  2 Runnable :就绪状态,当调用start方法,就处于就绪状态,但此时,并一定开始运行了,只是表示可以有运行资源,还要JVM里线程调度器的调度

  3 Running:运行状态,执行线程体

  4 Blocked:阻塞状态,是指暂停线程的执行以等待某个条件的发生

  5 dead:死亡状态,线程结束就处于死亡状态。

  6 Lock:锁定状态,同步加锁,在对共享资源的访问机制

6 线程状态转化图

7 控制线程方法

   1 void join():等待该线程终止

      当执行流调用其他线程的join方法,调用线程将被阻塞,直到join线程完成为止

范例

class RunnableDemo implements Runnable { // 线程的主体类
    @Override
    public void run() { // 线程的主方法
     	for(int i=0;i<5;i++){
    		System.out.println(Thread.currentThread().getName() + "--->" + i);
    	}
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
    	RunnableDemo rd = new RunnableDemo() ;//新建实现Runnable接口对象
    	Thread t1 = new Thread(rd,"线程1"); //声明并初始化Thread类对象,把事项Runnable接口对象作为实参
        t1.start() ;//调用start()启动线程
    	for(int i=0;i<5;i++){
    		System.out.println(Thread.currentThread().getName() + "--->" + i);
    		if(i==2){
    			t1.join(); //调用join方法,main主线程执行到i==5时,主线程进入阻塞状态,此时只有t1线程执行,直到t1执行完,才再次进入就绪状态
    		}
    	}
    }
}

输出结果
main--->0
main--->1
main--->2
线程1--->0
线程1--->1
线程1--->2
线程1--->3
线程1--->4
main--->3
main--->4

   2 void setDaemon(boolean on):将该线程标记为守护线程或用户线程

      也称为后台线程,当前台所有线程死亡时,被设置为后台线程随之死亡

   3 static void sleep(long millis):在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)

范例

class RunnableDemo implements Runnable { // 线程的主体类
    @Override
    public void run() { // 线程的主方法
     	for(int i=0;i<5000000;i++){
     		try {
				Thread.sleep(10); 
			} catch (Exception e) {}
    		System.out.println(Thread.currentThread().getName() + "--->" + i);
    	}
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
 
    	RunnableDemo rd = new RunnableDemo() ;//新建实现Runnable接口对象
    	Thread t1 = new Thread(rd,"线程1"); //声明并初始化Thread类对象,把事项Runnable接口对象作为实参
    	  t1.setDaemon(true); //设置为后台线程
        t1.start() ;//调用start()启动线程
       	for(int i=0;i<5;i++){
    		System.out.println(Thread.currentThread().getName() + "--->" + i);
    	}
    	//当for循环执行后,程序就结束
    }
}
输出结果
main--->0
main--->1
main--->2
main--->3
main--->4
线程1--->0
线程1--->1


class RunnableDemo implements Runnable { // 线程的主体类
    @Override
    public void run() { // 线程的主方法
     	for(int i=0;i<5000000;i++){
     		try {
				Thread.sleep(10); 
			} catch (Exception e) {}
    		System.out.println(Thread.currentThread().getName() + "--->" + i);
    	}
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
 
    	RunnableDemo rd = new RunnableDemo() ;//新建实现Runnable接口对象
    	Thread t1 = new Thread(rd,"线程1"); //声明并初始化Thread类对象,把事项Runnable接口对象作为实参
    	  t1.setDaemon(true); //设置为后台线程
        t1.start() ;//调用start()启动线程
       	for(int i=0;i<5;i++){
    		System.out.println(Thread.currentThread().getName() + "--->" + i);
    	}
    	//当for循环执行后,程序就结束
    }
}
输出结果
main--->0
main--->1
main--->2
main--->3
main--->4
线程1--->0
线程1--->1

   4 static void yield():暂停当前正在执行的线程对象,并执行其他对象

     只是放弃了执行权,但还是在就绪状态,当再次抢到执行权,还是可以继续执行的

  5 void setPriority(int newPriority):更改线程的优先级

     参数为:Thread.MAX_PRIORITY 最高优先级,10级

                    Thread.MIN_PRIORITY 最低优先级,1级

                    Thread.NORM_PRIORITY 默认优先级,5级

范例

class RunnableDemo implements Runnable { // 线程的主体类
    @Override
    public void run() { // 线程的主方法
     	for(int i=0;i<5;i++){
     		try {
				Thread.sleep(10); 
			} catch (Exception e) {}
    		System.out.println(Thread.currentThread().getName() + "--->" + i);
    		if(i==3){
    			Thread.yield();
    		}
    	}
    }
}

public class Test {
    public static void main(String[] args) throws Exception {
 
    	RunnableDemo rd = new RunnableDemo() ;//新建实现Runnable接口对象
    	Thread t1 = new Thread(rd,"高级线程1"); //声明并初始化Thread类对象,把事项Runnable接口对象作为实参
    	Thread t2 = new Thread(rd,"低级线程2"); //声明并初始化Thread类对象,把事项Runnable接口对象作为实参
    	t1.setPriority(Thread.MAX_PRIORITY); //设置该线程优先级为最高
    	t2.setPriority(Thread.MIN_PRIORITY); //设置该线程优先级为最低
        t1.start() ;//调用start()启动线程
        t2.start() ;//调用start()启动线程
    }
}

输出结果
高级线程1--->0
低级线程2--->0
高级线程1--->1
低级线程2--->1
高级线程1--->2
低级线程2--->2
高级线程1--->3
低级线程2--->3
低级线程2--->4
高级线程1--->4

8 线程同步

   线程同步是指当多个线程操作同一个资源时因为延迟之类问题引起信息安全问题

  实现线程同步方式:

  1 同步代码块

     在代码块上加上“synchronized“关键字,格式如下:

     synchronized (同步对象){

       ......//需要同步的代码

     }

  2 同步方法

     使用”synchronized“关键字将一个方法声明成同步方法,格式如下:

     synchronized 方法返回值 方法名称(参数列表){}

  当没有实现线程同步代码可能出现的问题卖票范例:

class MyThread implements Runnable{			// 实现Runnable接口
	private int ticket = 5 ;				// 一共5张票
	public void run(){				// 覆写run()方法
		for(int i=0;i<10;i++){			// 超出票数的循环
			if(ticket>0){			// 判断是否有剩余票
				try {
					Thread.sleep(100) ;	// 加入延迟
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("卖票:ticket = " + ticket--) ;
			}
		}
	}
};
public class Test {
	public static void main(String[] args) {
		MyThread mt = new MyThread() ;		// 定义线程对象
		Thread t1 = new Thread(mt) ;			// 定义Thread对象
		Thread t2 = new Thread(mt) ;			// 定义Thread对象
		Thread t3 = new Thread(mt) ;			// 定义Thread对象
		t1.start() ;				// 启动线程
		t2.start() ;				// 启动线程
		t3.start() ;				// 启动线程
	}
}
输出结果
卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1
卖票:ticket = 0
卖票:ticket = -1


使用同步代码块的卖票范例:

class MyThread implements Runnable{		// 实现Runnable接口
	private int ticket = 5 ;			// 一共5张票
	public void run(){				// 覆写run()方法
		for(int i=0;i<10;i++){			// 超出票数的循环
			synchronized (this) {		// 设置需要同步的操作	
				if(ticket>0){		// 判断是否有剩余票
					try {
						Thread.sleep(100) ;	// 加入延迟
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				    System.out.println("卖票:ticket = " + ticket--) ;
				}
			}
		}
	}
};

public class Test {
	public static void main(String[] args) {
		MyThread mt = new MyThread() ;		// 定义线程对象
		Thread t1 = new Thread(mt) ;			// 定义Thread对象
		Thread t2 = new Thread(mt) ;			// 定义Thread对象
		Thread t3 = new Thread(mt) ;			// 定义Thread对象
		t1.start() ;				// 启动线程
		t2.start() ;				// 启动线程
		t3.start() ;				// 启动线程
	}
}
输出结果
卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1


使用同步方法的卖票范例:

class MyThread implements Runnable{		// 实现Runnable接口
	private int ticket = 5 ;			// 一共5张票
	public void run(){				// 覆写run()方法
		for(int i=0;i<100;i++){			// 超出票数的循环
			this.sale();			// 调用同步方法
		}
	}
	public synchronized void sale() {		// 声明同步方法
		if(ticket>0){				// 判断是否有剩余票
			try {
				Thread.sleep(300) ;	// 加入延迟
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("卖票:ticket = " + ticket--) ;
		}
	}
};
public class Test {
	public static void main(String[] args) {
		MyThread mt = new MyThread() ;		// 定义线程对象
		Thread t1 = new Thread(mt) ;			// 定义Thread对象
		Thread t2 = new Thread(mt) ;			// 定义Thread对象
		Thread t3 = new Thread(mt) ;			// 定义Thread对象
		t1.start() ;				// 启动线程
		t2.start() ;				// 启动线程
		t3.start() ;				// 启动线程
	}
}
输出结果
卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1


9 同步锁

  从JDK1.5后,java提供了同步锁的线程同步机制,锁提供了共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程方为人共享资源之前先获得Lock对象,然后Lock对象调用lock()方法加锁,执行代码,最后调用unlock()方法解锁。

  格式如下:

class X {
	private final ReentrantLock lock = new ReentrantLock(); //定义锁对象
	
	//定义需要保证线程安全的方法
	public void m(){
		lock.lock(); 
		try{
			//需要保证线程安全的代码
		}finally{
			lock.unlock(); 
		}
	}
	
}

10  死锁

  当两个线程相互等待对方释放同步监视器是就会发生死锁,当发生死锁,所有线程处于阻塞状态,无法继续执行

死锁范例:

class Zhangsan{
	public void say(){
		System.out.println("张三对李四说:“先付钱,再收货。”");
	}
	public void get(){
		System.out.println("张三得到钱了。");
	}
}
class Lisi{
	public void say(){
		System.out.println("李四对张三说:“先收货,再付款。”");
	}
	public void get(){
		System.out.println("李四得到货了。");
	}
}
public class Test implements Runnable{
	private static Zhangsan zs = new Zhangsan(); 
	private static Lisi ls = new Lisi(); 
	private boolean flag = false; 
	public void run(){
		if(flag){
			synchronized (zs) {
				zs.say(); 
				try {
					Thread.sleep(500); 
				} catch (InterruptedException e) {
					e.printStackTrace(); 
				}
				synchronized (ls) {
					zs.get(); 
				}
			}
		}else{
			synchronized (ls) {
				ls.say(); 
				try {
					Thread.sleep(500); 
				} catch (InterruptedException e) {
					e.printStackTrace(); 
				}
				synchronized (zs) {
					ls.get(); 
				}
			}
		}
	}
	public static void main(String[] args) {
		Test d1 = new Test(); 
		Test d2 = new Test();
		d1.flag = true; 
		d2.flag = false;
		new Thread(d1).start(); 
		new Thread(d2).start(); 
		
	}
}
输出结果
张三对李四说:“先付钱,再收货。”
李四对张三说:“先收货,再付款。”

11 线程通信

   当线程在运行是,线程的调度具有一定的随机性和透明性,程序通常无法准确控制线程的轮换执行,但是可以通过一些机制俩保证线程协调运行

   1 可以借助Object类提供的wait(),notify()和notifyAll()三个方法

      wait():让当前线程放弃监视器进入等待,直到其他线程调用同一个监视器并调用notify()notifyAll()为止。

      notify():唤醒在同一对象监听器中调用wait方法的第一个线程。

      notifyAll():唤醒在同一对象监听器中调用wait方法的所有线程。

  2 可以通过同步锁机制Lock类提供的awit(),signal()和signalAll()方法

     await():  等价于同步监听器的wait()方法;

     signal(): 等价于同步监听器的notify()方法;

     signalAll(): 等价于同步监听器的notifyAll()方法;

生产者和消费者范例:

class Info{
	private String name = "张三"; 
	private String content = "学生";
	private boolean flag = false;
	public synchronized void set(String name,String content){
		if(!flag){
			try {
				super.wait(); 
			} catch (InterruptedException e) {
				e.printStackTrace(); 
			}
		}
		this.setName(name); 
		try {
			Thread.sleep(100); 
		} catch (InterruptedException e) {
			e.printStackTrace(); 
		}
		this.setContent(content);
		flag = false; 
		super.notify(); 
	}
	public synchronized void get(){
		if(flag){
			try {
				super.wait(); 
			} catch (InterruptedException e) {
				e.printStackTrace(); 
			}
		}
		try {
			Thread.sleep(100); 
		} catch (InterruptedException e) {
			e.printStackTrace(); 
		}
		System.out.println(this.getName() + "--->" + this.getContent());
		flag = true; 
		super.notify(); 
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
}
class Producer implements Runnable{
	private Info info = null; 
	public Producer(Info info){
		this.info = info; 
	}
	public void run(){
		boolean flag = false; 
		for(int i=0;i<50;i++){
			if(flag){
				this.info.set("张三","学生");
				flag = false; 
			}else {
				this.info.set("李四","老师");
				flag = true; 
			}
		}
	}
}
class Consumer implements Runnable{
	private Info info = null; 
	public Consumer(Info info){
		this.info = info; 
	}
	public void run(){
		for(int i=0;i<50;i++){
			this.info.get(); 
		}
	}
}
public class Test {
	public static void main(String[] args) {
		Info info = new Info(); 
		Producer p = new Producer(info); 
		Consumer c = new Consumer(info); 
		new Thread(p).start(); 
		new Thread(c).start(); 
	}

}
输出结果
张三--->学生
李四--->老师
张三--->学生
李四--->老师
张三--->学生
李四--->老师
张三--->学生
李四--->老师


------- android培训java培训、期待与您交流! ----------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
城市应急指挥系统是智慧城市建设的重要组成部分,旨在提高城市对突发事件的预防和处置能力。系统背景源于自然灾害和事故灾难频发,如汶川地震和日本大地震等,这些事件造成了巨大的人员伤亡和财产损失。随着城市化进程的加快,应急信息化建设面临信息资源分散、管理标准不统一等问题,需要通过统筹管理和技术创新来解决。 系统的设计思路是通过先进的技术手段,如物联网、射频识别、卫星定位等,构建一个具有强大信息感知和通信能力的网络和平台。这将促进不同部门和层次之间的信息共享、交流和整合,提高城市资源的利用效率,满足城市对各种信息的获取和使用需求。在“十二五”期间,应急信息化工作将依托这些技术,实现动态监控、风险管理、预警以及统一指挥调度。 应急指挥系统的建设目标是实现快速有效的应对各种突发事件,保障人民生命财产安全,减少社会危害和经济损失。系统将包括预测预警、模拟演练、辅助决策、态势分析等功能,以及应急值守、预案管理、GIS应用等基本应用。此外,还包括支撑平台的建设,如接警中心、视频会议、统一通信等基础设施。 系统的实施将涉及到应急网络建设、应急指挥、视频监控、卫星通信等多个方面。通过高度集成的系统,建立统一的信息接收和处理平台,实现多渠道接入和融合指挥调度。此外,还包括应急指挥中心基础平台建设、固定和移动应急指挥通信系统建设,以及应急队伍建设,确保能够迅速响应并有效处置各类突发事件。 项目的意义在于,它不仅是提升灾害监测预报水平和预警能力的重要科技支撑,也是实现预防和减轻重大灾害和事故损失的关键。通过实施城市应急指挥系统,可以加强社会管理和公共服务,构建和谐社会,为打造平安城市提供坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值