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

线程同步(像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 {@Overridepublic 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") {@Overridepublic 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 {@Overridepublic 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() {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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学习系列(十五)Java面向对象之细谈线程、线程通信(下)相关推荐

  1. Java学习系列(十八)Java面向对象之基于UDP协议的网络通信

    UDP协议:无需建立虚拟链路,协议是不可靠的. A节点以DatagramSocket发送数据包,数据报携带数据,数据报上还有目的目地地址,大部分情况下,数据报可以抵达:但有些情况下,数据报可能会丢失 ...

  2. Java学习系列(十六)Java面向对象之基于TCP协议的网络通信

    TCP/IP的网络分层模型:应用层(HTTP/FTP/SMTP/POPS...),传输层(TCP协议),网络层(IP协议,负责为网络上节点分配唯一标识),物理层+数据链路层). IP地址用于标识网络中 ...

  3. Java学习系列(十九)Java面向对象之数据库编程

    JDBC(Java Data Base Connectivity:java数据库连接):它定义了一组标准的操作数据库的接口,既然是接口,那它就是一种规范,是Java操作数据库的技术规范. Java数据 ...

  4. Java学习系列(十二)Java面向对象之序列化机制及版本

    序列化:内存中的Java对象<-->二进制流 目的:a)有时候需要把对象存储到外部存储器中持久化保存,b)还有时候,需要把对象通过网络传输. 可序列化的对象,Java要求可序列化的类实现下 ...

  5. Java学习系列(十四)Java面向对象之细谈线程、线程通信(上)

    线程与进程的关系: 进程 --运行中的程序.进程有如下特征: 1).独立性.拥有自己的资源,拥有自己独立的内存区. 通常来说,一个进程的内存空间,是不允许其他进程访问的. 但像Windows,如A进程 ...

  6. Java学习系列(十)Java面向对象之I/O流(上)

    IO流 我们知道应用程序运行时数据是保存在内存中的,但由于内存中的数据不可持久保存(如断电或程序退出时数据会丢失),因此需要一种手段将数据写入硬盘或读入内存.面向IO流编程就是一种很好的选择.IO:I ...

  7. java学习记录十五:集合二Collections、Set、Map

    java学习记录十五:集合二 一.Collections工具类 一.解释 二.常用方法 1.打乱集合顺序 2.按照默认规则排序 3.按指定规则排序 4.批量添加元素 二.可变参数 一.解释 二.写法 ...

  8. Java学习 第十五天

    Java学习 第十五天 第一章 StringBuilder类 1.1 字符串的不可变 1.2 StringBuilder概述 1.3 构造方法 1.4 两个常用方法 1.4.1 append方法 1. ...

  9. WorldWind学习系列十五:如何切割影像和DEM数据及其在WW中的应用配置

    原文转自:http://www.cnblogs.com/wuhenke/archive/2010/01/03/1638499.html WorldWind学习系列十四中我从代码上分析如何加载DEM数据 ...

最新文章

  1. TypeError: ‘instancemethod‘ object has no attribute ‘__getitem__‘
  2. Windows LTSC、LTSB、Server 安装 Windows Store 应用商店
  3. linux下查看网卡型号
  4. gitlab远程提交
  5. 【学术相关】研究生哪些行为可以在导师那超加分?你做到了吗?
  6. 工作中男女程序员对比,没注意原来差距这么大!你中招了吗?
  7. iOS pickerView(所有类型一网打尽)
  8. mysql操作符_MySql 中的=操作符
  9. Pytorch——DataLoader(批训练)
  10. Android ListView + ArrayAdapter、SimpleAdapter、BaseAdapter实现列表
  11. Swift - 实现tableView单选系统样式
  12. 穿越迷宫的函数c语言,数据结构课外实践题库(26页)-原创力文档
  13. linux服务器测试接口命令,Linux 下 TCP/UDP 端口测试及验证方法说明
  14. screentogif能录制声音吗_一款免费且强大的gif动画录制工具,再也不愁录动画!...
  15. netkeeper客户端_中国电信创翼客户端下载
  16. 2022-华为-大数据研发工程师-秋招面经
  17. 使用KMS批量激活操作系统
  18. 每日一句_《南柯子·池水凝新碧》
  19. 【实战案例】python进行自动网上考试
  20. Swoole---Http(协程风格)

热门文章

  1. java Exception 处理汇总
  2. IBM V3500存储更换控制器一例
  3. 客户网站被黑导致CDN加速后打开域名就提示域名纠错
  4. lucene bug的报告经历
  5. FreeMarker标签使用
  6. 终于找到个好办法备份数据库了
  7. C#/ASP.NET完善的DBHelper,配套Model生成器
  8. Java 集合 Collection、Iterator
  9. fuel部署openStack
  10. UIViewController内存管理