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 方法返回值  方法()  {}

死锁

不同的线程在互相等待

总结:

只要数据共享就需要同步

过分同步就会产生死锁

时间: 2024-10-10 05:48:09

12-24java面向对象之同步和死锁的相关文章

多线程——线程同步,死锁

线程同步: 为什么需要同步 ①   线程同步是为了防止多个线程访问一个数据对象时,对数据造成破坏. ②   线程的同步是保证多线程安全访问竞争资源的一种手段. 同步和锁 ①   Java中每一个对象都有一个内置锁. ②   当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁:当程序运行到synchronized同步代码块时,自动获得锁定对象的锁. ③   获得一个对象的锁也称为获取锁.锁定对象.在对象上锁定或在对象上同步.当程序运

Java入门——同步与死锁

Java入门——同步与死锁 同步 解决资源共享的同步操作,可以使用同步代码块和同步方法两种方法完成. 1 package Sep19; 2 3 class MyThread implements Runnable{ 4 private int ticket=5; 5 public void run(){//覆写run方法 6 for(int i=0;i<100;i++){ 7 if (ticket>0){ 8 try{ 9 Thread.sleep(3000); 10 }catch(Inter

线程的同步与死锁

在多线程中,同步与死锁概念很重要,在本章中必须了解以下几点: 1)哪里需要同步. 2)如何实现同步,了解代码即可. 3)及实现同步后有哪些副作用. 代码并不要求可以完整编写,但是概念必须清楚. 具体内容 1.1问题引出 以买火车票为例,不管多少地方可以买火车票,最终一趟列车的车票数量是固定的,如果把各个售票点理解为线程的话,则所有线程应该共同拥有同一份票数. package Thread1; class MyThread implements Runnable{ private int tick

java多线程(同步与死锁问题,生产者与消费者问题)

首先我们来看同步与死锁问题: 所谓死锁,就是A拥有banana,B拥有apple. A对B说:你把apple给我,我就把banana给你. B对A说:你把banana给我,我就把apple给你. 但是A和B都在等待对方的答复,那么这样最终的结果就是A得不到apple,B也得不到banana.这种死循环就是死锁. 于是我们可以模拟上面的描述,写出以下代码: 类A代表A这个人, public class A { public void say(){ System.out.println("A sai

多线程之同步与死锁

面试的时候被问到,在线性回归中,有三个假设,是哪三个? 当时回答出来自变量x和因变量y之间是线性变化关系,也就是说,如果x进行线性变化的话,y也会有相应的线性变化. 提到数据样本的时候也答道了样本点之间要求是独立同分布的(根据MLE准则,假定对样本加上高斯白噪声e的情况下). 但是第三个最终还是没有答上来,面试官也没有再给提示,所以回来自己再查一下. LR的wiki页面(http://en.wikipedia.org/wiki/Linear_regression)中,有提到了LR的假设,分别是:

Java多线程编程(三)线程的优先级、同步与死锁

线程的优先级: 线程的优先级分为三种,分别是: 1-MIN_PRIORITY 10-MAX_PRIORITY 5-NORM_PRIORITY 如果什么都不设置默认值是5 线程的优先级可以影响线程的执行顺序,当然这里指的是有可能影响,不会一定影响.在默认状态下(比如说主线程)它的默认值是5 具体代码演示: package com.yeqc.thread; class ThRun implements Runnable{ @Override public void run() { for(int i

C#:多线程、线程同步与死锁

推荐阅读: C#线程系列讲座(1):BeginInvoke和EndInvoke方法 C#线程系列讲座(2):Thread类的应用 C#线程系列讲座(3):线程池和文件下载服务器 C#线程系列讲座(4):同步与死锁 C#线程系列讲座(5):同步技术之Monitor C#中多线程同步的Monitor理解

ubuntu 12.04 server ntp同步

ubuntu和windows对计算机硬件保存的时间解释可能是不一样的.windows默认把硬件时间当做local time,而ubuntu把硬件时间当做UTC(Coordinated Universal Time 世界统一时间). ubuntu 默认开启UTC,不过可以关闭UTC,方法:sudo gedit /etc/default/rcS 把UTC=yes 修改成UTC=no .这样ubuntu就可以把硬件时间当做local time 了.如果您的ubuntu 服务器时间已经不准确了,可以用以

第12天 面向对象

第12天面向对象 今日内容介绍 构造方法 this super 构造方法 我们对封装已经有了基本的了解,接下来我们来看一个新的问题,依然以Person为例,由于Person中的属性都被private了,外界无法直接访问属性,必须对外提供相应的set和get方法.当创建人对象的时候,人对象一创建就要明确其姓名和年龄,那该怎么做呢? 构造方法介绍 在开发中经常需要在创建对象的同时明确对象的属性值,比如员工入职公司就要明确他的姓名.年龄等属性信息. 那么,创建对象就要明确属性值,那怎么解决呢?也就是在