黑马程序员_多线程的死锁和等待唤醒机制
2014-07-02 23:36
274 查看
------- android培训、java培训、期待与您交流!
----------
1. 死锁问题的发生一般是由于同步的嵌套但锁却不同,如下程序:
class MyLock {
static Object
locka = new Object();
static Object
lockb = new Object();
}
class DeadLock
extends MyLock implements Runnable {
private
boolean flag;
DeadLock(boolean flag) {
this.flag = flag;
}
public
void run() {
if (flag) {
//同步代码块的嵌套,锁不同
synchronized (locka) {
System.out.println("if locka");
synchronized (lockb) {
System.out.println("if lockb");
}
}
} else {
//同步代码块的嵌套,锁不同
synchronized (lockb) {
System.out.println("else lockb");
synchronized (locka) {
System.out.println("else locka");
}
}
}
}
}
public
class Test{
public
static void main(String[] args) {
new Thread(new DeadLock(true)).start();
new Thread(new DeadLock(false)).start();
}
}
在两个相互嵌套的同步代码块中,锁不相同,当各自拿着对方的锁不放时就会出现死锁现象。
2. 多线程的等待唤醒机制
class Student {
private String
name;
private
int age;
static
boolean flag =
false;
public
synchronized void set(String name,
int age) {
if (flag)
//等待,所有等待的线程都存放在线程池里
try{this.wait();}catch(Exception e){}
this.name = name;
this.age = age;
flag =true;
//唤醒,首先唤醒第一个被等待的线程
this.notify();
}
public
synchronized void out() {
if (!flag)
//等待,所有等待的线程都存放在线程池里
try{this.wait();}catch(Exception e){}
System.out.println("name:" +
name + "age:" +
age);
flag =
false;
//唤醒,首先唤醒第一个被等待的线程
this.notify();
}
}
class Input
extends Student implements Runnable {
private Student
s;
Input(Student s){
this.s=s;
}
public
void run() {
int x = 0;
while (true) {
if (x == 0)
s.set("林青霞", 27);
else
s.set("擎天柱", 5000);
x = (x + 1) % 2;
}
}
}
class Output
extends Student implements Runnable {
private Student
s;
Output(Student s){
this.s=s;
}
public
void run() {
while (true) {
s.out();
}
}
}
public
class Test11 {
public
static void main(String[] args) {
Student s=new Student();
new Thread(new Input(s)).start();
new Thread(new Output(s)).start();
}
}
wait();
notify();
notifyAll();
都使用在同步中,因为要对持有监视器(锁)的线程操作
所以要使用在同步中,因为只有同步才具有锁
为什么这些方法要定义在Object类中呢?
因为这些方法在操作同步中的线程时,都必须要标识他们所操作线程持有的锁
只有同一个锁上的被等待线程,才可以被同一个锁上的notify()唤醒
不可以对不同锁中的线程进行唤醒
也就是说,等待和唤醒必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中。
----------
1. 死锁问题的发生一般是由于同步的嵌套但锁却不同,如下程序:
class MyLock {
static Object
locka = new Object();
static Object
lockb = new Object();
}
class DeadLock
extends MyLock implements Runnable {
private
boolean flag;
DeadLock(boolean flag) {
this.flag = flag;
}
public
void run() {
if (flag) {
//同步代码块的嵌套,锁不同
synchronized (locka) {
System.out.println("if locka");
synchronized (lockb) {
System.out.println("if lockb");
}
}
} else {
//同步代码块的嵌套,锁不同
synchronized (lockb) {
System.out.println("else lockb");
synchronized (locka) {
System.out.println("else locka");
}
}
}
}
}
public
class Test{
public
static void main(String[] args) {
new Thread(new DeadLock(true)).start();
new Thread(new DeadLock(false)).start();
}
}
在两个相互嵌套的同步代码块中,锁不相同,当各自拿着对方的锁不放时就会出现死锁现象。
2. 多线程的等待唤醒机制
class Student {
private String
name;
private
int age;
static
boolean flag =
false;
public
synchronized void set(String name,
int age) {
if (flag)
//等待,所有等待的线程都存放在线程池里
try{this.wait();}catch(Exception e){}
this.name = name;
this.age = age;
flag =true;
//唤醒,首先唤醒第一个被等待的线程
this.notify();
}
public
synchronized void out() {
if (!flag)
//等待,所有等待的线程都存放在线程池里
try{this.wait();}catch(Exception e){}
System.out.println("name:" +
name + "age:" +
age);
flag =
false;
//唤醒,首先唤醒第一个被等待的线程
this.notify();
}
}
class Input
extends Student implements Runnable {
private Student
s;
Input(Student s){
this.s=s;
}
public
void run() {
int x = 0;
while (true) {
if (x == 0)
s.set("林青霞", 27);
else
s.set("擎天柱", 5000);
x = (x + 1) % 2;
}
}
}
class Output
extends Student implements Runnable {
private Student
s;
Output(Student s){
this.s=s;
}
public
void run() {
while (true) {
s.out();
}
}
}
public
class Test11 {
public
static void main(String[] args) {
Student s=new Student();
new Thread(new Input(s)).start();
new Thread(new Output(s)).start();
}
}
wait();
notify();
notifyAll();
都使用在同步中,因为要对持有监视器(锁)的线程操作
所以要使用在同步中,因为只有同步才具有锁
为什么这些方法要定义在Object类中呢?
因为这些方法在操作同步中的线程时,都必须要标识他们所操作线程持有的锁
只有同一个锁上的被等待线程,才可以被同一个锁上的notify()唤醒
不可以对不同锁中的线程进行唤醒
也就是说,等待和唤醒必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中。
相关文章推荐
- 黑马程序员——Java基础——多线程的同步、死锁和等待唤醒机制
- 黑马程序员——java多线程之死锁和等待唤醒机制
- 黑马程序员 多线程的等待唤醒机制的理
- 黑马程序员-多线程部分(三.等待唤醒机制)
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
- 黑马程序员_多线程等待唤醒机制简单入门
- 黑马程序员-JAVA基础-多线程间的通信、等待唤醒机制和新特性
- 黑马程序员—多线程(下)--多线程安全问题及唤醒等待机制
- Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解
- 多线程(十一)---等待唤醒机制原理
- 多线程之间的友好通信-等待唤醒机制
- 多线程-生产者消费者之等待唤醒机制代码优化
- Java---18---多线程:等待唤醒机制
- 黑马程序员--等待唤醒机制
- 多线程__【线程间通信】【等待唤醒机制】【多生产多消费】【Lock&Condition接口】
- Java多线程---------同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期
- java 多线程-————等待唤醒机制
- 多线程(6)等待唤醒机制Lock,condition
- java 中多线程之间的通讯之等待唤醒机制