12-24java面向对象之同步和死锁

案例1

设计一个线程操作类,要求可以产生三个线程对象,并可以设置三个线程的休眠时间

分析:

1.使用Thread类实现

class MyThread extends Thread
{
	//封装属性
	private String name ;		//定义该线程的名称
	private int time;			//定义休眠时间
	//构造方法
	public MyThread(String name , int time)
	{
		super(name);
		this.time = time;
	}
	//覆写run方法
	public void run()
	{
		System.out.println(Thread.currentThread().getName() + "休眠开始");
		try
		{
			Thread.currentThread().sleep(this.time);
		}
		catch (InterruptedException e)
		{
			System.out.println(Thread.currentThread().getName() +"休眠中断");
		}
		System.out.println(Thread.currentThread().getName() + "休眠结束" + "持续:" + this.time + "ms");
	}
}
public class TestThread16
{
	public static void main(String[] args)
	{
		MyThread mt1 = new MyThread("线程A",1000);
		mt1.start();
		MyThread mt2 = new MyThread("线程B",2000);
		mt2.start();
		MyThread mt3 = new MyThread("线程C",3000);
		mt3.start();
	}
}

1.使用Runnable接口实现

class MyThread implements Runnable
{
	//封装属性
	private String name ;
	private int time ;
	//构造方法
	public MyThread(String name , int time)
	{
		this.name = name ;
		this.time = time ;
	}
	public String getName()
	{
		return this.name ;
	}
	//覆写run方法
	public void run()
	{
		System.out.println(this.name + "休眠开始");
		try
		{
			Thread.currentThread().sleep(this.time);
		}
		catch (InterruptedException e)
		{
			System.out.println(this.name +"休眠中断");
		}
		System.out.println(this.name + "休眠结束" + "持续:" + this.time + "ms");
	}
}
public class TestThread17
{
	public static void main(String[] args)
	{
		MyThread mt1 = new MyThread("线程A",1000);
		new Thread(mt1).start() ;
		MyThread mt2 = new MyThread("线程B",2000);
		new Thread(mt2).start() ;
		MyThread mt3 = new MyThread("线程C",3000);
		new Thread(mt3).start() ;
	}
}

同步

问题的引出:把各个售票点理解为线程,那么各个线程需要共享资源。如果引入延时,系统可能存在负数的问题。

class Sale implements Runnable
{
	private int ticket = 5;
	public void run()
	{
		for (int i =0;i<50 ; ++i )
		{
			if (ticket>0)
			{
				System.out.println("买票成功,还剩下票数 ticcket=" + ticket--);
			}
		}
	}
}
public class TestChronized1 
{
	public static void main(String[] args) 
	{
		Sale s = new Sale();
		Thread th1 = new Thread(s);
		Thread th2 = new Thread(s);
		Thread th3 = new Thread(s);
		th1.start();
		th2.start();
		th3.start();
	}
}

下面引入延时

class Sale implements Runnable
{
	private int ticket = 5;
	public void run()
	{
		for (int i =0;i<50 ; ++i )
		{
			if (ticket>0)
			{
				try
				{
					Thread.sleep(500);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
				System.out.println("买票成功,还剩下票数 ticcket=" + ticket--);
			}
		}
	}
}
public class TestChronized1 
{
	public static void main(String[] args) 
	{
		Sale s = new Sale();
		Thread th1 = new Thread(s);
		Thread th2 = new Thread(s);
		Thread th3 = new Thread(s);
		th1.start();
		th2.start();
		th3.start();
	}
}

结果

技术分享

要想解决数据共享问题——使用同步代码块或同法方法。

同步代码块

class Sale implements Runnable
{
	private int ticket = 5;
	public void run()
	{
		for (int i =0;i<50 ; ++i )
		{
			synchronized (this)
			{
				if (ticket>0)
				{
					try
					{
						Thread.sleep(500);
					}
					catch (InterruptedException e)
					{
						e.printStackTrace();
					}
					System.out.println("买票成功,还剩下票数 ticcket=" + ticket--);
				}
			}			
		}
	}
}
public class TestChronized2 
{
	public static void main(String[] args) 
	{
		Sale s = new Sale();
		Thread th1 = new Thread(s);
		Thread th2 = new Thread(s);
		Thread th3 = new Thread(s);
		th1.start();
		th2.start();
		th3.start();
	}
}

 同步代码块:

Synchronized (同步对象){}

其中同步对象一般使用this代替

 

同步方法

class Sale implements Runnable
{
	private int ticket = 5;
	public void run()
	{
		for (int i =0;i<50 ; ++i )
		{		
			saleTicket();
		}
	}
	public synchronized void saleTicket()
	{
		if (ticket>0)
			{
				try
				{
					Thread.sleep(500);
				}
				catch (InterruptedException e)
				{
					e.printStackTrace();
				}
				System.out.println("买票成功,还剩下票数 ticcket=" + ticket--);
			}		
	}
}
public class TestChronized3 
{
	public static void main(String[] args) 
	{
		Sale s = new Sale();
		Thread th1 = new Thread(s);
		Thread th2 = new Thread(s);
		Thread th3 = new Thread(s);
		th1.start();
		th2.start();
		th3.start();
	}
}

结果完全相同

Synchronized 方法返回值  方法()  {}

死锁

不同的线程在互相等待

总结:

只要数据共享就需要同步

过分同步就会产生死锁

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。