1)死锁

两个线程相互等待对方释放同步监视器时会出现死锁的现象,这时所有的线程都处于阻塞状态,程序无法继续向下执行。

如下就是会出现死锁的程序。

首先flag = 1,线程d1开始执行,锁住对象o1,sleep0.5s,同时线程2开始执行,flag = 0;锁住对象o2;sleep1.5s,执行线程切换到d1,此时要锁住对象o2,但是o2正在被线程d2锁住,线程切换到d2,d2要锁住o1,但是o1正在被d1对象锁住。出现了两个线程相互等待对方释放锁。都处于阻塞状态,程序等待,无法继续执行。

/*
*@author wxismeit@163.com
*/
public class DeadLock implements Runnable{
	public int flag;
static Object o1 = new Object();
static Object o2 = new Object(); public void run() {
System.out.println("flag = " + flag);
if(flag == 1) {
synchronized(o1) {
try {
Thread.sleep(500);
}catch(Exception e) {
e.printStackTrace();
} synchronized(o2) {
System.out.println(1);
}
} }
if(flag == 0) {
synchronized(o2) {
try {
Thread.sleep(500);
}catch(Exception e) {
e.printStackTrace();
} synchronized(o1) {
System.out.println(0);
}
}
}
}
public static void main(String[] args) {
DeadLock d1 = new DeadLock();
DeadLock d2 = new DeadLock();
d1.flag = 1;
d2.flag = 0;
Thread t1 = new Thread(d1);
Thread t2 = new Thread(d2);
t1.start();
t2.start();
}
}

2)线程同步模拟生产者与消费者问题。

首先明确wait方法与sleep方法的区别 :wait方法是Object类的方法,导致当前线程等待。知道有其他的线程调用notify或者notifyAll方法唤醒这个线程。但是wait方法会先释放锁,然后让其他线程执行,而sleep方法则不同。wait方法必须是用synchronized修饰的同步方法或者对象才可以调用。

用模拟线程安全的栈的方法来做产品的容器。生产者消费者各为一个模拟线程。利用线程同步来处理生产与消费的关系。

代码如下 :

public class Producer implements Runnable {
private Storage storage;
public Producer(Storage s) {
storage = s;
}
public void run() {
Product p = new Product("DELL", "computer");
storage.Push(p);
} }
public class Consumer implements Runnable{
private Storage storage; public Consumer(Storage s) {
storage = s;
} public void run() {
storage.Pop();
} }
public class Product {
private String Id;
private String name; public Product(String Id, String name) {
this.Id = Id;
this.name = name;
} public String getId() {
return Id;
}
public void setId(String Id) {
this.Id = Id;
} public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} @Override
public String toString() { return "Id : " + Id + " name : " + name;
} }
import java.util.Stack;

public class Storage {
private Product[] product = new Product[10];
private int top = 0;// public synchronized void Push(Product p) {
if(top == product.length) {
try {
wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
product[top++] = p;
System.out.println(Thread.currentThread().getName() + " 生产了 :" + p);
notifyAll();
}
public synchronized Product Pop() {
if(top == 0) {
try {
wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
--top;
Product pp = new Product(product[top].getId(), product[top].getName());
product[top] = null;
System.out.println(Thread.currentThread().getName() + "消费了 :" + pp);
notifyAll();
return pp;
} } <pre class="java" name="code">public class ProducerAndConsumer { public static void main(String[] args) {
Storage s = new Storage();
Thread consumer = new Thread(new Consumer(s));
Thread producer = new Thread(new Producer(s));
consumer.setName("消费者");
producer.setName("生产者");
consumer.start();
producer.start();
} }

//完美运行


评论区留下邮箱可获得《Java所线程设计模式》

转载请指明来源

Java多线程详解(三)的更多相关文章

  1. Java 多线程详解(四)------生产者和消费者

    Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html Java 多线程详解(二)------如何创建进程和线程: ...

  2. Java多线程详解(二)

    评论区留下邮箱可获得<Java多线程设计模式详解> 转载请指明来源 1)后台线程 后台线程是为其他线程服务的一种线程,像JVM的垃圾回收线程就是一种后台线程.后台线程总是等到非后台线程死亡 ...

  3. java多线程详解(6)-线程间的通信wait及notify方法

    Java多线程间的通信 本文提纲 一. 线程的几种状态 二. 线程间的相互作用 三.实例代码分析 一. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种:(1). 产生(New) ...

  4. Java多线程详解

    Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...

  5. 原创Java多线程详解(一)

    只看书不实践是不行的.来实践一下~~~~~~(引用请指明来源) 先看看百科对多线程的介绍 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的 ...

  6. Java 多线程详解(一)------概念的引入

    这是讲解 Java 多线程的第一章,我们在进入讲解之前,需要对以下几个概念有所了解. 1.并发和并行 并行:指两个或多个时间在同一时刻发生(同时发生): 并发:指两个或多个事件在一个时间段内发生. 在 ...

  7. Java 多线程详解(三)------线程的同步

    Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html Java 多线程详解(二)------如何创建进程和线程: ...

  8. java多线程详解(7)-线程池的使用

    在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, 这样频繁创建线程就会大大降低系 ...

  9. java多线程详解(3)-线程的互斥与同步

    前言:前一篇文章主要描述了多线程中访成员变量与局部变量问题,我们知道访成员变量有线程安全问题,在多线程程序中 我们可以通过使用synchronized关键字完成线程的同步,能够解决部分线程安全问题 在 ...

随机推荐

  1. Java基本功—Reference

    这是一篇一年多之前便已写就的文章,那时,因为很多Java程序员只求追随新生的事物,却连基本的概念都没有,很多讨论中,很明显是基本功不过硬,于是萌生写一个系列文章,讨论Java的基本功,下面便是在这个想 ...

  2. Liunx下NFS服务器的搭建与配置

    一.NFS简介 NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NF ...

  3. Entity Framework管理实体关系(一):管理一对一关系

    我们现在已经知道如何使用Code First来定义简单的领域类,并且如何使用DbContext类来执行数据库操作.现在我们来看下数据库理论中的多样性关系,我们会使用Code First来实现下面的几种 ...

  4. Using org.hibernate.id.UUIDHexGenerator which does not generate IETF RFC 4122 compliant UUID values;

    项目部署,启动过程中有以下警告: [WARN]: Using org.hibernate.id.UUIDHexGenerator which does not generate IETF RFC 41 ...

  5. 开源图形数据库Neo4j介绍与安装

    图形数据库是以图形结构形式存储数据的数据库. https://neo4j.com/ Java 编写 保存为节点以及节点之间的关系 Neo4j 的数据由下面几部分构成: 节点 边 属性 无论是顶点还是边 ...

  6. C++/C语言的标准库函数与运算符的区别new/delete malloc/free

    malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符.它们都可用于申请动态内存和释放内存.下面来看他们的区别. 一.操作对象有所不同 malloc与free是C++ ...

  7. Spring事务:调用同一个类中的方法

    问题: 如果同一个类中有方法:methodA(); methodB().methodA()没有开启事务,methodB()开启了事务 且methodA()会调用methodB(). 那么,method ...

  8. python中时间操作总结

    一.time 二.datetime 1.获取当前系统时间 datenow = datetime.datetime.now() 2.将datetime格式的时间转换成str datenow = date ...

  9. C# winform 获取当前路径

    // 获取程序的基目录. System.AppDomain.CurrentDomain.BaseDirectory// 获取模块的完整路径.System.Diagnostics.Process.Get ...

  10. 2014Esri全球用户大会之影像和栅格

    1.现在Esri已将影像作为GIS解决方案的一部分,其详细战略部署是如何的? 在过去的十年.Esri有规划的在ArcGIS平台(主要为Desktop和Server)中管理和开发影像和栅格功能.这包含影 ...