黑马程序员_JavaSE基础13 之 线程创建 线程安全 同步代码块

----------------------      android培训java培训、期待与您交流!   ---------------------
JavaSE_13  笔记 
                          Java语言基础之  线程创建  线程安全 同步代码块
 
1、 线程的四种状态
①创建——start();
②运行——run();
该状态下的线程具备CPU的执行资格(可以被处理,在处理对了中排队)和CPU的执行权(正在被cpu处理)。
③冻结——sleep(time);  wait() ; 唤醒——notify(); 
释放执行权,同时释放执行资格。
④消亡——stop();
 
2、创建线程的第二中方式——实现Runnable接口,
   ①使用情况:Java不支持多继承,当一个类已经继承了一个父亲时,为了实现多线程,便有了使用接口来扩展其功能。
   ②步骤:定义类实现Runnable接口;覆盖接口中的run方法,将线程的任务代码封装到run方法中;通过Thread类创建线程对象,并将Runnable接口的子类对象作为构造函数的参数进行传递;最后调用线程对象的start方法开启线程。
 
3、线程事例之卖票1 : 创建4个对象,不能实现共卖100张票。
class Ticket extends Thread
{
	private int num=100;
	public void run()
	{
While(true)
{
If(num>0)
{
				System.out.println(Thread.currentThread. getName()+”....sale......”num--);
}
}
	}
}
 
class  TicketDemo//创建4个卖票对象,相当于开始了4个线程;而每个线程都执行一次卖100张票的过程
{
	public static void main(String[] args) 
	{
		Ticket t1=new Ticket(); 
		Ticket t2=new Ticket(); 
		Ticket t3=new Ticket(); 
		Ticket t4=new Ticket(); 
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}
 
 
4、线程事例之卖票2 : 创建1个对象,能实现共卖100张票。
class Ticket implements Runnable
{
	private int num=100;
	public void run()
	{
While(true)
{
If(num>0)
{
				System.out.println(Thread.currentThread. getName()+”....sale......”num--);
}
}
	}
}
 
class  TicketDemo//创建一个对象,却开启了4个线程共用一个对象,即Num.
{
	public static void main(String[] args) 
	{
		Ticket t=new Ticket();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		Thread t3=new Thread(t);
		Thread t4=new Thread(t);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
 
	}
}
  
5、线程事例之卖票3 : 线程安全问题
If(num>0)  // 当thread-0拿到num=0,此时thread-1得到执行权,由于num还没有执行操作,还是0,所以会出现
{
				System.out.println(Thread.currentThread. getName()+”....sale......”num--);
}
线程安全问题分析:
①多个线程在操作共享的数据;②操作共享数据的线程代码有多条。
 
6、线程安全问题解决方法:在java中,使用同步代码块来解决,就是把共享数据代码封装起来。
 ①格式: synchronized (对象) {  //需要被同步的代码;   }
 ②同步的好处:解决了线程的安全问题;同步的弊端:降低了效率,应为同步外的线程都会判断同步锁。
 ③同步的前提:同步中必须有多个线程并使用同一个锁。
 ④事例:
class Ticket implements Runnable
{
	private int num=100;
	Object obj=new Object(); // 创建锁,同时注意位置,不能再run()内,因为唯一.
	public void run()
	{
		while(true)
		{
			synchronized(obj) //同步代码块
			{
				if(num>0)
				{
					System.out.println(Thread.currentThread().getName()+"....sale...."+ num--);//当前第几线程正在卖第几张票
				}
			}
		}
	}
}
 
7、线程事例之存钱 1: 有共享数据,存在数据安全问题。
//两个储户存款3次,每次存储100元
class Bank
{
 
	private sum ; //线程安全问题1、有共享数据 sum ; 2、有多个线程操作
	public void add(int num)
	{
		sum+=num;
	}
}
 
class Cus implements Runnable
{
	public void run()
	{
		Bank b=new Bank();
		for(int i=0;i<3;i++)
		{
			b.run();
		}
	}
}
 
class  TicketDemo//创建一个对象,却开启了4个线程共用一个对象,即Num.
{
	public static void main(String[] args) 
	{
		Cus s=new Cus();
		Thread t1=new Thread(c);
		Thread t2=new Thread(c);
		t1.start();
		t2.start();
	}
}
 
8、线程事例之存钱 2: 使用同步代码块,加锁,来解决数据安全问题。
//两个储户存款3次,每次存储100元
class Bank
{
	private sum ; 
	Object obj=new Object();
	synchronized(obj)  //解决方法,使用锁
	{
		public void add(int num)
		{
			sum+=num;
		}
	}
}
 
9、同步函数和同步代码块的区别:
①同步函数的锁是固定的this。
public synchronized void add(int num){ }
②同步代码块的锁是固定的this。
 
10、静态同步函数
  静态的同步函数使用的锁是该函数所属的字节码文件对象,可以用getClass方法获取,也可以使用当前  类名.class 表示。
 
 
                                                                  2012/9/09     By  Mary_k
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值