JAVA线程同步与死锁

原创 2013年04月30日 17:21:23

         上一篇写到了JAVA初步认识线程,现在就说说自己对线程同步及死锁的认识。

      线程的同步,是为了避免多个线程访问相同的数据对象时,对数据造成破坏。

     下面模拟多个售票员销售同一列车的票。

一.同步

package thread;

public class MyThread  implements Runnable{
    private   int ticket=5;
   
	@Override
	public void run(){
		for(int i=1;i<=100;i++){
			this.sale();
		}
	}
	private  void sale(){
		if(ticket>0){
			try {
				Thread.sleep(1000);//卖票耗时模拟
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"卖出票 "+(ticket--));
		}
		  
	}
}

package thread;

public class ThreadClient {
	public static void main(String[] args) {
		MyThread t1=new MyThread();
		for(int i=0;i<10;i++){
			new Thread(t1,"售票员"+(i+1)).start();
		}
	}
}


运行结果:

售票员1卖出票 4
售票员3卖出票 5
售票员5卖出票 3
售票员2卖出票 2
售票员4卖出票 1
售票员6卖出票 0
售票员8卖出票 -1
售票员10卖出票 -2
售票员7卖出票 -3
售票员9卖出票 -4
售票员1卖出票 -5
售票员3卖出票 -6
售票员5卖出票 -7
售票员2卖出票 -8

         看运行结果,居然出现了负数,这明显不符合实际。简单分析下。

(1)假如售票员1查看ticket,发现ticket=1,还可以继续出售,但卖票需要填写一些数据什么的,需要话费时间。

(2)售票员1还在填写票据,1号票还没卖出。此时售票员2也查看了下ticket,发现ticket=1,他认为还可以继续出售(他不知道售票员1准备出售1号票)他也准备填写票据了。

(3)在售票员2在填写出售1号的数据时,售票员1完成了填写出售1号票的数据,并将它出售了,ticket=0了,没票出售了(但是售票员2不知道)

(4)售票员2填写完数据了,让电脑打印票,这是才发现票上面写的居然是0了

 

       这种情况就是所谓的线程不安全。那么可以使用synchronized,对出售票的动作进行加锁,在同一个时间点,只允许一个人在卖票。

package thread;

public class MyThread  implements Runnable{
    private   int ticket=5;
   
	@Override
	public void run(){
		for(int i=1;i<=100;i++){
			this.sale();
		}
	}
	private synchronized  void sale(){
		if(ticket>0){
			try {
				Thread.sleep(1000);//卖票耗时模拟
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"卖出票 "+(ticket--));
		}
		  
	}
}




package thread;

public class ThreadClient {
	public static void main(String[] args) {
		MyThread t1=new MyThread();
		for(int i=0;i<10;i++){
			new Thread(t1,"售票员"+(i+1)).start();
		}
	}
}


 

运行结果

售票员2卖出票 5
售票员2卖出票 4
售票员9卖出票 3
售票员7卖出票 2
售票员7卖出票 1


     运行结果符合实际了。

二、死锁

       使用synchronized可以解决同步问题,但是如果使用不当,会发生死锁问题。

       画画需要笔和纸。张三和李四同时想画画,张三拿到了笔,李四拿到了纸。张三在等李四给纸他,李四在等张三给笔他。于是他们两人都在等待。这就是死锁了。

package thread;

public class Pane {

	public String toString(){
		return "神奇的七彩笔.........";
	}
	
}
package thread;

public class Paper {

	public String toString(){
		return "白花花的画纸......";
	}
	
}


 

package thread;

public class DeadLockTest {

	public static void main(String[] args) {
		DrawPicture zs=new DrawPicture("张三");
		DrawPicture ls=new DrawPicture("李四");
		new Thread(zs).start();
		new Thread(ls).start();
	}
}


运行结果

李四得到了白花花的画纸......
张三得到了神奇的七彩笔.........

     程序打印了上面两个结果后,就卡住了(是2个线程都在等待,进入了堵塞状态)。张三和李四谁也不能完成画画。。。。都在等待对方,给资源。

 

 
 
 
 
 
 
 
 

 

相关文章推荐

JAVA_线程同步与死锁

  • 2012年08月16日 11:45
  • 32KB
  • 下载

Java 线程同步与死锁 学习笔记

Java 线程同步与死锁 学习笔记Java 线程同步与死锁 学习笔记 1 多线程共享数据 2 线程同步 3 同步准则 4 线程死锁 1、 多线程共享数据 在多线程操作中,多个线程可能同时处理同一个资源...

Java多线程之线程同步和死锁

Java多线程之线程同步和死锁 

Java线程同步与死锁、生产者消费者模式以及任务调度等

Thread类基本信息方法 线程同步 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个...

Java多线程 线程同步与死锁

1.线程同步多线程引发的安全问题一个非常经典的案例,银行取钱的问题。假如你有一张银行卡,里面有5000块钱,然后你去银行取款2000块钱。正在你取钱的时候,取款机正要从你的5000余额中减去2000的...

Java笔记(4)-线程、Thread、Runable、开子线程、线程运行状态、线程同步、线程死锁

蓬山此去无多路,青鸟殷勤为探看。—李商隐《无题》 线程 线程的基本定义 线程和进程 在 Java 当中实现线程的两种方法使用Thread 或Runnable 线程运行状态介绍 线程间通信的方法 线程...

Java笔记六.线程同步、线程死锁

线程同步、线程死锁     在上一篇文章中,有一个模拟售卖火车票系统,在卖车票的程序代码中,极有可能碰到一种意外,就是同一张票号被打印两次多次,也可能出现打印出0甚至负数的票号。具体表现为:假设tic...

Java中的线程同步及线程死锁复习

1 线程安全 在单线程程序中,每次只能做一件事情,后面的事情需要等待前面的事情完成后才可以进行,但是如果使用多线程程序,就会发生多个线程抢占资源的问题,从而产生线程安全问题。实质上线程安全问题来源于多...

Java多线程-(8)线程同步、锁、死锁

一、线程同步、锁 至于怎么用或者原理就不做太多讲述了,只总结了下要注意的点: 1、Java中每个对象都有一个内置锁;当提到同步时,应该清楚在什么上同步?也就是说,在哪个对象上同步? 2、非静...

java 多线程(4) 线程同步之锁(synchronized) / 死锁 / 两个锁定对象期间访问(修改)其变量的面试

锁就是synchronized,记住synchronized(this )是锁定当前对象 package test.java.Thread; public class TestSync imple...
  • nx188
  • nx188
  • 2016年01月13日 14:53
  • 1618
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAVA线程同步与死锁
举报原因:
原因补充:

(最多只允许输入30个字)