I学霸官方免费教程四十一 :Java基础教程之线程死锁

线程死锁

是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的线程称为死锁线程。

例如:某一商店有两个人PS和PB在做交易,PS手里拿着货物对PB说,你先给我钱我在给你货,而PB拿着钱对PS说你先给我货我在给你钱。两个人就此僵持下去,永远也无法做成交易,这就构成了死锁。

实例:
package thread.deadlock;
/**
 * 创建DeadlockDemo类:用于测试死锁
 * @author 学霸联盟 - 赵灿
 */
public class DeadlockDemo {
	public static void main(String[] args) {
		//创建一个Shop对象
		Shop shop = new Shop();
		//创建两个线程对象
		ThreadBuy tBuy = new ThreadBuy(shop);
		ThreadSell tSell = new ThreadSell(shop);
		tBuy.start();
		tSell.start();
	}
}

/**
 * 创建Cargo(货物)类:仅仅为了创建对象,获取对象锁
 * @author 学霸联盟 - 赵灿
 */
class Cargo{ }
/**
 * 创建Money(货物)类:仅仅为了创建对象,获取对象锁
 * @author 学霸联盟 - 赵灿
 */
class Money{ }
/**
 * 创建Shop(商店)类
 * @author 学霸联盟 - 赵灿
 */
class Shop {
	//创建Cargo对象
	private Cargo cargo = new Cargo();
	//创建Money对象
	private Money money = new Money();
	//buyer方法完成买家想要的功能
	public void buyer() {
		//买家手里拿着钱,对应到代码上就是获得money对象的锁
		synchronized (money) {
			System.out.println("买家拿着钱说:先交货");
			try {
				//模拟等待卖家交货的时间
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			//买家拿着钱的同时想要把货也拿到手里,再交出钱
			synchronized (cargo) {
				System.out.println("买家:成交");
			}
		}
	}
	//seller方法完成卖家想要的功能
	public void seller() {
		//卖家手里拿着货,对应到代码上就是获得cargo对象的锁
		synchronized (cargo) {
			System.out.println("卖家拿着货说:先交钱");
			try {
				//模拟等待买家交钱的时间
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			//卖家拿着货的同时想要把钱也拿到手里,再交出货
			synchronized (money) {
				System.out.println("买家:成交");
			}
		}
	}
}

/**
 * 创建ThreadBuy类
 * @author 学霸联盟 - 赵灿
 */
class ThreadBuy extends Thread{
	private Shop  shop;
	public ThreadBuy(Shop shop){
		this.shop = shop;
	}
	@Override
	public void run() {
		//购买的线程,执行购买的方法
		shop.buyer();
	}
}

/**
 * 创建ThreadSell类
 * @author 学霸联盟 - 赵灿
 */
class ThreadSell extends Thread{
	private Shop  shop;
	public ThreadSell(Shop shop){
		this.shop = shop;
	}
	@Override
	public void run() {
		//卖出的线程,执行卖出的方法
		shop.seller();
	}
}
运行结果:
卖家拿着货说:先交钱
买家拿着钱说:先交货

死锁导致交易永远无法达成

线程优先级

线程优先级的本意是用于标识线程获得CPU的几率的高低,但线程调度不是绝对按照优先级的顺序调度的,这与操作系统和JVM有关。

java中对线程的优先级定义了10个级别,范围:1(Thread.MIN_PRIORITY )~ 10 (Thread.MAX_PRIORITY )),但不同的系统有不同的线程优先级的取值范围,这样就有可能多个线程优先级对应某种操作系统里有的同一优先级,所以很多时候设置优先级看不到不同优先级之间的差别。

自定义线程的优先级默认是父线程类的优先级

Thread类的默认优先级是5(Thread.NORM_PRIORITY)

设置线程优先级使用setPriority(int)方法

实例:
package thread.priority;
/**
 * 创建父线程
 * @author 学霸联盟 - 赵灿
 */
public class FatherThread extends Thread {
	// 声明一个无参数的构造方法
	public FatherThread() {
		// 设置当前类对象的优先级为8
		this.setPriority(8);
	}
}

package thread.priority;
/**
 * 创建子线程
 * @author 学霸联盟 - 赵灿
 */
public class SonThread extends FatherThread {
	public static void main(String[] args) {
		// 创建SonThread对象,并使用创建的对象调用start方法启动线程
		new SonThread().start();
	}

	@Override
	public void run() {
		/*
		 * 使用关键字this调用getPriority方法,获取当前线程的优先级
		 * 并通过输出语句System.out.println将获取到的优先级输出
		 */
		System.out.println("子线程的优先级:" + this.getPriority());
	}
}
运行结果:
子线程的优先级:8

后台线程

在系统的后台运行,不与用户直接交互;这样的线程称为后台线程(也称服务线程或守护线程)。

例如:文件下载

setDaemon();//将线程设置为后台线程

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-05 02:39:17

I学霸官方免费教程四十一 :Java基础教程之线程死锁的相关文章

I学霸官方免费教程一:Java软件开发预备知识

一.     计算机系统简介 1.硬件系统:看得见,摸得着 主机:主机箱.主板.内存.硬盘.CPU(中央处理器).声卡.显卡.网卡 外设:显示器.音响 输入设备:键盘.鼠标.扫描仪 输出设备:显示器.投影仪.音响 2.软件系统 系统软件:windows.Linux.IOS.Unix.Android: 编译软件:编程语言,编译器,解释器 应用软件:除了以上的全是应用软件,比如聊天软件,网站,游戏软件等等 二.     软件简介 软件:按照特定顺序组织的计算机数据和指令的集合:其中指令是指挥计算机如

I学霸官方免费教程三十一:Java集合框架之List集合

集合框架 在数组的使用过程中可以看到,想要向数组中插入元素和删除元素非常麻烦,而且数组的长度是无法改变的.java为我们提供了批量存储数据更加方便的容器,就是集合.集合和数组的作用一样,都是为了使用一个变量来存储一批数据的:但集合使用起来更加方便,而且集合的长度是可以变化的. List接口 List集合可以存储有序的,可重复的数据:常用的子类是ArrayList和LinkedList两个类 ArrayList类 这是一个底层由数组实现的集合类,是对数组进行了封装. 实例: package col

I学霸官方免费教程三十二:Java集合框架之Set集合

Set接口 Set集合是无序的.元素不可重复的结合常用集合类有HashSet和TreeSet HashSet类常用的两种List集合各有各的优点,那么有没有同时具备这两种List集合的优点的集合呢?答案是肯定的,就是Set集合. 实例: package collection.set.hashSet; import java.util.HashSet; import java.util.Iterator; /**  * 演示HashSet  * @author 学霸联盟 - 赵灿  */ publ

Java基础教程:JDBC编程

Java基础教程:JDBC编程 快速开始 什么是JDBC JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库. JDBC API 库包含下面提到的每个任务,都是与数据库相关的常用用法. 制作到数据库的连接. 创建 SQL 或 MySQL 语句. 执行 SQL 或 MySQL 查询数据库. 查看和修改所产生的记录. 从根本上来说,JDBC 是一种规范,它提供了一套完整的接口,允许便携式访问到底层数据库,因此可以用 J

Java基础教程(25)--I/O流

??I/O流表示输入源或输出目标.流可以表示许多不同类型的源和目标,例如磁盘文件.设备.其他程序等. ??流支持许多不同类型的数据,包括字节.原始数据类型.字符和对象等.有些流只传递数据; 有些流则可以操纵和转换数据. ??无论各种流的内部是如何工作的,所有流都提供相同的简单模型:流是一系列数据.程序使用输入流从源头获取数据,一次一项: ??程序使用输出流将数据写入目的地,一次一项: ??在本文中,我们会看到流可以处理各种各样的数据,无论是基本数据还是复杂对象.先来几张IO流的全家福: ??In

Java基础教程 - 组合

1. 什么是组合? 如果一个类的对象和另一个类满足"has-a"关系的话,我们就可以在一个类中,把另一个类的对象作为其对象成员. 什么是"has-a"关系,举个例子:现在有一个类LapTop.class,还有一个是Moniter.class.好显然,Laptop "has-a" Moniter,也就是说,他们是满足"has-a"关系的.这时候,我们就可以把Moniter作为Laptop的一个数据成员. class Laptop

四、Android学习第四天——JAVA基础回顾(转)

(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 四.Android学习第四天——JAVA基础回顾 这才学习Android的第四天,在程序中已经遇到了JAVA中以前不常用的一些知识点,赶紧回顾复习一下,打下基础 这里就做个简单的小结: 一.匿名内部类 匿名内部类说白了就是个没有被命名的JAVA类 在以下条件下使用匿名内部类比较适合: ①只用到该类的一个实例时 ②类在定义后被马上用到 ③类非常小(SUN推荐是在4行代码以下

Java基础教程:面向对象编程

Java基础教程:面向对象编程 Java语言概述 Java语言特点 1.Java为纯面向对象的语言,它能够直接反映现实生活中的对象.总之,Everything is object! 2.平台无关性.Java为解释型语言,编译器会把Java代码变成"""中间代码",然后在JVM上解释执行. 3.Java提供了很多内置的类库,这些类库简化了开发人员的程序设计工作,同时缩短了项目开发时间. 4.Java语言提供了对Web应用的支持. 5.Java语言提供了较好的安全性和健

Java基础教程:面向对象编程[2]

Java基础教程:面向对象编程[2] 三大特性 封装 封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装.隐藏起来的方法.封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问. 使用封装我们可以对成员变量进行更精确的控制,同时隐藏信息,实现细节等. 方法: public class Person{ private String name; private int age; ? public int getAge(){ return age;

Java基础教程:HashTable与HashMap比较

Java基础教程:HashTable与HashMap比较 1.  关于HashMap的一些说法: a)  HashMap实际上是一个"链表散列"的数据结构,即数组和链表的结合体.HashMap的底层结构是一个数组,数组中的每一项是一条链表. b)  HashMap的实例有俩个参数影响其性能: "初始容量" 和 装填因子. c)  HashMap实现不同步,线程不安全.  HashTable线程安全 d)  HashMap中的key-value都是存储在Entry中的