`

Java学习系列(十五)Java面向对象之细谈线程、线程通信(下)

 
阅读更多

竞争资源(共享资源):如果有多条线程需要并发访问、并修改某个对象,该对象就是“竞争资源”。为了避免多个线程"自由竞争”修改共享资源所导致的不安全问题。

线程同步(像Vector、Hashtable等都是线程安全的):
解决线程异步有两种方式:

1)同步代码块(需要显式的指定同步监视锁);
2).同步方法(相当于使用方法的调用者,如果方法是实例方法,相当于this为同步监视锁;如果方法是类方法,相当于类作为同步监视锁)。
它们的实现机制是完全相同的,当线程要进入被"同步监视锁"监视的代码之前,线程必须先获得“同步监视锁”,这样就可以保证在任意一个时刻,只有一条线程能进入被"同步监视锁"监视的代码。从程序逻辑来看,选择“竞争资源”作为同步监视锁。
举例说明1--同步代码块(由于代码都是些属性,所以这里只抽取了片段,掌握思想即可):

 

// 同步代码块,synchronized后的括号中的对象被称为同步锁
		synchronized (account) {
			if (account.getBalance() > drawAmount) {
				System.out.println("取钱成功,吐出钱数:" + drawAmount);
				account.setBalance(account.getBalance() - drawAmount);
				System.out.println("还剩余额为:" + account.getBalance());
			} else {
				System.out.println("取钱失败,余额不足!");
			}
		}


举例说明2:--同步方法,以this作为同步监视锁。

public synchronized void draw(double drawAmount){
		if (getBalance() > drawAmount) {
			System.out.println("取钱成功,吐出钱数:" + drawAmount);
			setBalance(getBalance() - drawAmount);
			System.out.println("还剩余额为:" + getBalance());
		} else {
			System.out.println("取钱失败,余额不足!");
		}
	}

 

线程同步的关键:任何同步监视器监视的代码之前,必须先对同步监视器加锁。

何时释放对【同步监视器】的加锁?
1.同步代码块或同步方法执行完成。
2.在代码中遇到了break、return语句跳出该代码块。
3.执行同步代码块或同步方法时遇到未捕获的异常时。
4.调用了同步监视器的wait()方法。

【注意】使用sleep()、yield()都不会释放。

线程通信:
1.如果不加控制,多个线程“自由”地并发执行。
2.可以通过同步,来解决多个线程并发访问竞争资源的问题。线程安全,必然降低性能。
3.如果希望线程之间能更有序地执行。

线程组ThreadGroup与未处理的异常:
怎样把线程放入指定的线程组中呢? --在创建一个Thread实例时,通过传入的ThreadGroup对象,即可将该线程放入指定的线程组中,进而通过线程组对这批线程进行整体的管理。
ThreadGroup提供了如下两个方法:setDaemon(boolean daemon) 控制将线程组本身都设置为后台线程组,并不是将它所包含的线程设为后台线程。setMaxPriority(优先级):它是设置该线程组已有的线程的优先级不会受影响,对以后新添加的线程的优先级才会有影响。

对线程异常进行处理:在JDK1.5之前,系统会自动回调它所在线程组的uncaughtException(Thread t,Throwable e)方法来修复该异常;在JDK1.5之后,线程允许自行设置“异常处理器”,无需线程组。public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh):为所有线程设置默认的异常处理器。public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh):为当前线程实例设置异常处理器。

举列说明1(jdk1.5之前):

 

public class ThreadExceptionTest implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + "--->" + i
					/ (i - 20));
		}
	}

	public static void main(String[] args) {
		// 创建一个线程组
		ThreadGroup tg = new ThreadGroup("mytg") {
			@Override
			public void uncaughtException(Thread t, Throwable e) {
				System.out.println(t.getName() + "出现了异常,信息是:" + e.getMessage());
			}
		};
		ThreadExceptionTest test = new ThreadExceptionTest();
		new Thread(tg, test).start();
	}

}

举列说明2(jdk1.5之后):

 

 

public class ThreadExceptionTest implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + "--->" + i
					/ (i - 20));
		}
	}

	public static void main(String[] args) {
		// 为所有线程设置默认的异常处理器
		Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
			@Override
			public void uncaughtException(Thread t, Throwable e) {
				System.out.println(t.getName() + "出现了异常,信息是:" + e.getMessage());
			}
		});
		ThreadExceptionTest test = new ThreadExceptionTest();
		new Thread(test).start();
	}
}

 

线程池(Pool):池的本质,就是一种“缓存”技术。是否要缓存一个对象,要看该对象的创建成本。
Executors --创建线程池,线程工厂的工具类。ExecutorService:它就是线程池。
缓存的本质:牺牲空间(内存)来换取时间。线程对象的创建成本比较大(尽管比创建进程的成本小的多,但相对普通java对象,Thread的创建成本依然较大),为解决这个问题,我们用线程池。

编程步骤:
1.通过Executors的静态工厂方法创建ExecutorService或ScheduledExecutorService
2.调用ExecutorService的方法提交线程即可。
3.调用线程池的.shutdown方法关闭线程池。

举例说明1:

public class ThreadPoolTest implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + ",i=" + i);
		}
	}

	public static void main(String[] args) {
		ExecutorService es = Executors.newFixedThreadPool(10);
		es.submit(new ThreadPoolTest());
		es.shutdownNow();// 关闭线程池
	}
}

举例说明2:

 

 

public class ThreadPoolTest implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + ",i=" + i);
		}
	}

	public static void main(String[] args) {
		ScheduledExecutorService es = Executors.newScheduledThreadPool(10);
		// 延迟5s,以后每隔2s执行一次run方法
		es.scheduleAtFixedRate(new ThreadPoolTest(), 5, 2, TimeUnit.SECONDS);
	}
}

 



分享到:
评论

相关推荐

    面向对象程序设计JAVA 多线程自学教程ppt

    面向对象程序设计JAVA 多线程自学教程ppt

    漫画面向对象编程 Java

    面向对象的简、由类创建一个对象的方法、类的编写与对象的创建、类的构造函数、类的方法、修饰符、Java中的封装/继承/多态等特征、Java中的线程、用Java创建一个小世界、多线程共享数据,以及面向对象中的各种设计...

    java面向对象编程源码

    全书内容包括面向对象的编程思想、Java语言的基础知识、异常处理、类与对象的生命周期、多线程、Java集合、输入/输出和GUI编程等。其最大特色是以六条主线贯穿全书:面向对象编程思想、Java语言的语法、Java虚拟机...

    Java面向对象程序设计课后答案全解

    本资源包含了该课程所有章节的课后习题答案,帮助学习者深入理解Java语言的面向对象特性。 1. **类与对象**:Java中的基本构建块是类,它代表了现实世界中的事物或概念。对象则是类的实例,具有类定义的属性和行为...

    JAVA面向对象程序设计(期末考试试题及答案)

    本文总结了 JAVA面向对象程序设计的知识点,涵盖了 Java 语言的基本语法、面向对象编程的概念、异常处理、多线程编程、网络编程、数据库编程等方面的知识,为学习和掌握 Java 语言提供了有价值的参考。

    Java 线程通信示例 源代码

    在Java编程中,多线程通信是一个至关重要的概念,特别是在设计高效的并发应用程序时。这个"Java线程通信示例源代码"很可能包含了演示如何在不同线程之间共享数据和协调执行顺序的实例。线程通信主要涉及两个核心概念...

    Java基础教程完整版

    Java学习系列(十五):Java面向对象之细谈线程、线程通信(下) 本章节主要讲解Java的线程编程,包括线程的通信、线程的等待和通知等。 Java学习系列(十六):Java面向对象之基于TCP协议的网络通信 本章节主要...

    面向对象与多线程java实验.zip

    武汉理工大学面向对象与多线程Java综合实验源码 完成时间:2020/11/11 实验目的 运用Java语言,以迭代方式逐步编程实现一个小型档案管理系统。由此了解软件开发的一般过程,深入理解面向对象语言的基本概念和基本...

    java多线程通信图解

    java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,这时B线程再从主线程获取该变量的值,这样就实现了...

    Java语言与面向对象程序设计

    Java语言以其面向对象特性、平台无关性、安全性和多线程能力而备受青睐。 首先,学生需要掌握Java的基础知识,包括简单的Java程序设计。这涉及到学习如何使用基本的语法结构,如变量定义、数据类型、运算符、流程...

    java面向对象程序设计(董小园版)收集.pdf

    Java 面向对象程序设计(董小园版)收集.pdf ...本书是学习 Java 面向对象程序设计的优秀资源,涵盖了面向对象的基本概念、对象的属性和行为、继承和多态、异常处理、图形界面编程和多线程机制等方面的知识。

    Java面向对象程序设计教程PDF,完整的面向对象编程指南,大量习题便于自学。

    Java面向对象程序设计是Java语言的核心特性之一,也是学习Java编程不可或缺的部分。本教程全面深入地探讨了这一主题,旨在帮助初学者和有一定基础的开发者更深入地理解面向对象编程的概念和实践。以下是对该教程内容...

    面向对象编程C++和Java比较教程 中英文完整版 pdf

    本教程对比了两种广泛应用的面向对象语言——C++和Java,帮助读者深入理解两者之间的异同。 C++是Bjarne Stroustrup于1983年创建的,它是C语言的扩展,增加了类、模板、异常处理等面向对象特性。C++强调性能和灵活...

    java面向对象和多线程实验

    在Java编程语言中,面向对象和多线程是两个核心且重要的概念,它们在实际的软件开发中扮演着至关重要的角色。在这个名为“java面向对象和多线程实验”的项目中,我们可以深入探讨这两个主题。 面向对象(Object-...

    java面向对象程序设计第3版本参考答案

    Java 面向对象程序设计是 Java 语言的核心概念之一,对于 Java 程序员来说,掌握面向对象程序设计是非常重要的。本资源将为您提供 Java 面向对象程序设计的相关知识点,涵盖了 Java 的基础知识、面向对象编程的基本...

    Java面向对象程序设计课本例题源代码

    清华大学的耿祥义教授编写的教材是许多学习者深入理解Java面向对象编程的首选资料。这个压缩包中包含的就是这本教材中的例题源代码,对于初学者和进阶者来说都是宝贵的实践资源。 1. **面向对象编程基础**:Java是...

    《Java2面向对象程序设计基础》线程.ppt

    在Java 2面向对象程序设计中,线程是内置支持的特性,使得Java成为构建并发应用的理想选择。 6.1 线程简介 线程可以理解为程序执行的独立路径,它们共享同一份程序资源,比如内存空间和代码。程序是静态的代码集合...

    java 面向对象程序设计课件

    Java是一种广泛使用的面向对象编程语言,它以其平台独立性、高效性和丰富的类库而闻名。在"java 面向对象程序设计课件"中,我们可以深入探讨以下几个关键知识点: 1. **面向对象编程基础**:Java是面向对象的语言,...

    Java语言面向对象程序设计实验指导与习题答案

    这本书旨在帮助读者深入理解Java语言的面向对象特性,并通过一系列的实验指导和习题解答,提升实践能力。 在Java语言中,面向对象编程(Object-Oriented Programming,OOP)是其核心概念之一。它基于类和对象的概念...

    Java多线程学习Java多线程学习Java多线程学习Java多线程学习.txt

    Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java多线程学习Java...

Global site tag (gtag.js) - Google Analytics