从头认识多线程-2.5 当异常出现时,线程自动释放锁

这一章节我们来讨论一下下面的情况:当异常出现时,线程自动释放锁。

1.一般情况

package com.ray.deepintothread.ch02.topic_6;

import java.util.Random;

public class ReleaseTheLockWhenException {
	public static void main(String[] args) throws InterruptedException {
		MyTestObjectOne myTestObjectOne = new MyTestObjectOne();
		ThreadOne threadOne = new ThreadOne(myTestObjectOne);
		Thread thread = new Thread(threadOne);
		thread.start();
		ThreadTwo threadTwo = new ThreadTwo(myTestObjectOne);
		Thread thread2 = new Thread(threadTwo);
		thread2.start();
	}
}

class ThreadOne implements Runnable {

	private MyTestObjectOne myTestObjectOne;

	public ThreadOne(MyTestObjectOne myTestObjectOne) {
		this.myTestObjectOne = myTestObjectOne;
	}

	@Override
	public void run() {
		try {
			myTestObjectOne.service_1();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class ThreadTwo implements Runnable {

	private MyTestObjectOne myTestObjectOne;

	public ThreadTwo(MyTestObjectOne myTestObjectOne) {
		this.myTestObjectOne = myTestObjectOne;
	}

	@Override
	public void run() {
		try {
			myTestObjectOne.service_2();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class MyTestObjectOne {
	public synchronized void service_1() throws InterruptedException {
		System.out.println("service_1 begin");
		System.out.println("service_1 working");
		Thread.sleep(1000);
		System.out.println("service_1 end");
	}

	public synchronized void service_2() throws InterruptedException {
		System.out.println("service_2 begin");
		System.out.println("service_2 working");
		Thread.sleep(1000);
		System.out.println("service_2 end");
	}
}

输出:

service_1 begin
service_1 working
service_1 end
service_2 begin
service_2 working
service_2 end

从输出和之前的文章我们可以知道,上面的情况是哪个线程先得到锁,就先执行,然后执行完了,才到下一个线程得到锁,因此输出结果是一个方法一个方法的输出

2.我们加上人造异常的情况

package com.ray.deepintothread.ch02.topic_6;

import java.util.Random;

public class ReleaseTheLockWhenException {
	public static void main(String[] args) throws InterruptedException {
		MyTestObjectOne myTestObjectOne = new MyTestObjectOne();
		ThreadOne threadOne = new ThreadOne(myTestObjectOne);
		Thread thread = new Thread(threadOne);
		thread.start();
		ThreadTwo threadTwo = new ThreadTwo(myTestObjectOne);
		Thread thread2 = new Thread(threadTwo);
		thread2.start();
	}
}

class ThreadOne implements Runnable {

	private MyTestObjectOne myTestObjectOne;

	public ThreadOne(MyTestObjectOne myTestObjectOne) {
		this.myTestObjectOne = myTestObjectOne;
	}

	@Override
	public void run() {
		try {
			myTestObjectOne.service_1();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class ThreadTwo implements Runnable {

	private MyTestObjectOne myTestObjectOne;

	public ThreadTwo(MyTestObjectOne myTestObjectOne) {
		this.myTestObjectOne = myTestObjectOne;
	}

	@Override
	public void run() {
		try {
			myTestObjectOne.service_2();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class MyTestObjectOne {
	public synchronized void service_1() throws InterruptedException {
		System.out.println("service_1 begin");
		System.out.println("service_1 working");
		{// 人造异常
			String a = null;
			a.toString();
		}
		Thread.sleep(1000);
		System.out.println("service_1 end");
	}

	public synchronized void service_2() throws InterruptedException {
		System.out.println("service_2 begin");
		System.out.println("service_2 working");
		Thread.sleep(1000);
		System.out.println("service_2 end");
	}
}

输出:

service_1 begin

Exception in thread "Thread-0" 
service_1 working
service_2 begin
service_2 working
java.lang.NullPointerException
at com.ray.deepintothread.ch02.topic_6.MyTestObjectOne.service_1(ReleaseTheLockWhenException.java:59)
at com.ray.deepintothread.ch02.topic_6.ThreadOne.run(ReleaseTheLockWhenException.java:28)
at java.lang.Thread.run(Thread.java:745)
service_2 end

从上面的输出可以看见,当线程0出现异常的时候,紧接着线程1就开始执行,对比上面的结果,由此可见,当出现异常的时候,线程0已经释放锁,让其他的线程得到锁继续执行下去。

总结:这一章节我们讨论了一下当异常出现时,线程自动释放锁的情况。

这一章节就到这里,谢谢

------------------------------------------------------------------------------------

我的github:https://github.com/raylee2015/DeepIntoThread

目录:http://blog.csdn.net/raylee2007/article/details/51204573

时间: 2024-10-14 23:13:24

从头认识多线程-2.5 当异常出现时,线程自动释放锁的相关文章

Operating System-Thread(5)弹出式线程&&使单线程代码多线程化会产生那些问题

本文主要内容 弹出式线程(Pop-up threads) 使单线程代码多线程化会产生那些问题 一.弹出式线程(Pop-up threads) 以在一个http到达之后一个Service的处理为例子来介绍弹出式线程. 上面的例子中传统的做法有可能是在Service中有一个线程一直在等待request的到达,等request到达后这个线程会开始检查请求最后在进行处理.当这个线程在处理request的时候,后面来的request会被block,一直到线程处理完当前request为止.如下图所示. 弹出

从头认识多线程-2.8 缓解同步方法的隐患-同步代码块

这一章节我们来讨论一下缓解同步方法的隐患-同步代码块. 1.思路:把同步方法,降低同步的粒度,同步到代码块 2.根据上一章节的例子,我们把代码修改一下 (1)第一种方法,把同步标记移到更新的那一栏里面去,一般来说大部分都是更新的时候需要同步数据 package com.ray.deepintothread.ch02.topic_9; /** * 从头认识多线程-2.8 缓解同步方法的隐患-同步代码块<br> * * @author RayLee * */ public class Relief

线程同步-iOS多线程编程指南(四)-08-多线程

首页 编程指南 Grand Central Dispatch 基本概念 多核心的性能 Dispatch Sources 完结 外传:dispatch_once(上) Block非官方编程指南 基础 内存管理 揭开神秘面纱(上) 揭开神秘面纱(下) iOS多线程编程指南 关于多线程编程 线程管理 Run Loop 线程同步 附录 Core Animation编程指南 Core Animation简介 基本概念 渲染架构 几何变换 查看目录 中文手册/API ASIHTTPRequest Openg

Java之------多线程(从基础到加强及交互线程)

一.基础篇: 1.线程的定义 线程(thread)是操作系统进程中能够独立执行的实体(控制流),是处理器调度和分派的基本单位. 2.线程的属性 并发性,共享性,动态性,结构性 3.线程的状态 4.线程的调度 ★主要是通过实现Runnable接口和继承Thread类来实现线程的调度和操作 a.Runnable接口(里面就一个run方法,只要通过重写run方法就可以实现自己想要的线程功能) [java] view plain copy public interface Runnable { publ

多线程十大经典案例之一 双线程读写队列数据

本文配套程序下载地址为:http://download.csdn.net/detail/morewindows/5136035 转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/8646902 欢迎关注微博:http://weibo.com/MoreWindows 在<秒杀多线程系列>的前十五篇中介绍多线程的相关概念,多线程同步互斥问题<秒杀多线程第四篇一个经典的多线程同步问题>及解决多线程同步互斥的常用方法

C#多线程实践——提前释放锁

一个被阻止的线程可以通过两种方式被提前释放: 使用Thread.Interrupt 使用Thread.Abort 释放一个线程的锁必须通过另外活动的线程实现,等待的线程自己是不能对它的被阻止状态做任何事情. Interrupt方法 在一个被阻止的线程上调用Interrupt 方法,将强制释放它,同时抛出ThreadInterruptedException异常,如下: class Program { static void Main() { Thread t = new Thread (deleg

秒杀多线程第十六篇 多线程十大经典案例之一 双线程读写队列数据

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 本文配套程序下载地址为:http://download.csdn.net/detail/morewindows/5136035 转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/8646902 欢迎关注微博:http://weibo.com/MoreWindows 在<秒杀多线程系列>的前十五篇中介绍多线程的相关概念,多线程同步互斥问题<秒杀多

java多线程学习之——多线程中几种释放锁和不释放锁的操作

在学习java多线程这一块知识的时候,遇到了很多个关于线程锁什么时候释放的问题,现总结几种释放锁和不释放锁的操作如下: 不释放锁: 线程执行同步代码块或同步方法时,程序调用Thread.sleep(Long l).Thread.yield()方法暂停当前线程的执行 线程执行同步代码块时,其它线程调用该线程suspend()方法将该线程挂起,该线程不会释放锁(同步监视器) 尽量避免使用suspend()和resume()来控制线程 释放锁: 当前线程的同步方法.同步代码块执行结束 当前线程的同步方

实现多线程的同时复制(三个线程同时复制)

1 package com.threadcopyfile; 2 3 /** 4 * @author lisj 5 * 实现多线程的同时复制 6 * 调用多个线程同时复制各自的模块 7 */ 8 public class threadCopy { 9 10 11 public static void main (String args[]){ 12 13 ThreadCopyFile a=new ThreadCopyFile(1); //实例化多个线程 14 ThreadCopyFile b=ne