Java多线程与线程安全



一.线程与进程:

(一).进程:是一个正在执行中的程序。

                 每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。

 

(二)..线程

 

1含义:就是进程中的一个独立的控制单元(执行路径,执行情景)

                   线程在控制着进程的执行。一个进程中至少有一个线程。Java VM启动时,只好有两个线程:jvm的主线程(这个线程运行的代码存在于main方法中)、jvm的垃圾回收线程。

 

2.线程的五种状态:

(1).新建:新建线程,

(2).就绪:线程争夺CPU的执行权,具有执行资格,但没有执行权,

(3).运行:争夺到CPU执行权的线程开始执行,具有执行资格和执行权,

(4).阻塞:通过sleep方法和wait方法使线程停止运行,sleep方法指定时间内就会醒来,wait方法必须要等待唤醒,两个方法没有执行资格和执行权,一旦醒来,会重新进入就绪状态。

(5).死亡:有两种形式,1是线程执行完毕后线程停止,2人为的通过stop方法使线程停止

 

3.如何在自定义的代码中,自定义一个线程呢?

(1).创建线程的第一种方式:继承Thread类。

  步骤:

  1).定义类继承Thread

  2).复写Thread类中的run方法。目的:将自定义代码存储在run方法。让线程运行。

  3).调用线程的start方法,该方法两个作用:启动线程,调用run方法。run方法,用于存储线程要运行的代码。

             

                     //如果直接运行对象.run();实际上是main线程在运行。

 

(2).创建线程的第二种方式:实现Runnable(接口)

                           步骤:

1).继承Thread类。

2).覆盖run方法。将线程要运行的代码定义其中。

3).创建Thread类的子类对象,其实就是在创建线程,调用start方法。

 

(3).实现方式(Runnable)和继承方式(Thread)有什么区别呢?

 

实现方式好处:避免了单继承的局限性。在定义线程时,建立使用实现方式。

两种方式区别:继承Thread:线程代码存放Thread子类run方法中。实现Runnable,线程代码存在接口的子类的run方法。

 

.线程安全

 

().多线程出现安全问题原因:多线程具备随机性。因为是由cpu不断的快速切换造成的,就有可能会产生多线程的安全问题。

 

问题的几个关键点:

1.多线程代码中有操作共享数据。

2.多条语句操作该共享数据。

当具备两个关键点时,有一个线程对多条操作共享数据的代码执行的一部分。还没有执行完,另一个线程开始参与执行。

就会发生数据错误。

 

().解决方法(同步):当一个线程在执行多条操作共享数据代码时,其他线程即使获取了执行权,也不可以参与操作。Java就对这种解决方式提供了专业的代码。

 

1.同步的原理:就是将部分操作功能数据的代码进行加锁。

 

2.同步的表现形式:

1).同步代码块:同步代码块使用的锁是任意对象。

2).同步函数:同步函数使用的锁是this,对于static的同步函数,使用的锁不是this。是类名.class是该类的字节码文件对象。

 

3.同步的好处:解决了线程的安全问题。弊端:较为消耗资源,同步嵌套后,容易死锁。

 

().两种同步:

 

1.(synchronized代码块和函数):

/*
同步函数用的是哪一个锁呢?
函数需要被对象调用。那么函数都有一个所属对象引用。就是this。
所以同步函数使用的锁是this。

通过该程序进行验证。

使用两个线程来买票。
一个线程在同步代码块中。
一个线程在同步函数中。
都在执行买票动作。



*/
class Ticket implements Runnable
{
	private  int tick = 100;
	Object obj = new Object();
	boolean flag = true;
	public  void run()
	{
		if(flag)
		{
			while(true)
			{
				synchronized(this)
				{
					if(tick>0)
					{
						try{Thread.sleep(10);}catch(Exception e){}
						System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
					}
				}
			}
		}
		else
			while(true)
				show();
	}
	public synchronized void show()//this
	{
		if(tick>0)
		{
			try{Thread.sleep(10);}catch(Exception e){}
			System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
		}
	}
}


class  ThisLockDemo
{
	public static void main(String[] args) 
	{

		Ticket t = new Ticket();

		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		t1.start();
		try{Thread.sleep(10);}catch(Exception e){}
		t.flag = false;
		t2.start();







//		Thread t3 = new Thread(t);
//		Thread t4 = new Thread(t);
//		t3.start();
//		t4.start();


	}
}


2.(Lock唤醒对方线程)

/*
JDK1.5 中提供了多线程升级解决方案。
将同步Synchronized替换成现实Lock操作。
将Object中的wait,notify notifyAll,替换了Condition对象。
该对象可以Lock锁 进行获取。
该示例中,实现了本方只唤醒对方操作。

Lock:替代了Synchronized
	lock 
	unlock
	newCondition()

Condition:替代了Object wait notify notifyAll
	await();
	signal();
	signalAll();
*/
class Resource
{
	private String name;
	private int count = 1;
	private boolean flag = false;
			//  t1    t2
	private Lock lock = new ReentrantLock();

	private Condition condition_pro = lock.newCondition();
	private Condition condition_con = lock.newCondition();



	public  void set(String name)throws InterruptedException
	{
		lock.lock();
		try
		{
			while(flag)
				condition_pro.await();//t1,t2
			this.name = name+"--"+count++;

			System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
			flag = true;
			condition_con.signal();
		}
		finally
		{
			lock.unlock();//释放锁的动作一定要执行。
		}
	}


	//  t3   t4  
	public  void out()throws InterruptedException
	{
		lock.lock();
		try
		{
			while(!flag)
				condition_con.await();
			System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
			flag = false;
			condition_pro.signal();
		}
		finally
		{
			lock.unlock();
		}
		
	}
}

class Producer implements Runnable
{
	private Resource res;

	Producer(Resource res)
	{
		this.res = res;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				res.set("+商品+");
			}
			catch (InterruptedException e)
			{
			}
			
		}
	}
}

class Consumer implements Runnable
{
	private Resource res;

	Consumer(Resource res)
	{
		this.res = res;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				res.out();
			}
			catch (InterruptedException e)
			{
			}
		}
	}
}


():多线程的优先级和停止线程:

1.多线程的优先级:thread.t1.setPriority(int  newPriority); //newPriority取值1-10

2.停止线程:

       stop过时。原理:run方法结束。run方法中通常定义循环,指定控制住循环线程即可结束。

 

       1,定义结束标记。

       2,当线程处于了冻结状态,没有执行标记,程序一样无法结束。

              这时可以循环,正常退出冻结状态,或者强制结束冻结状态。

              强制结束冻结状态:interrupt();目的是线程强制从冻结状态恢复到运行状态。

              但是会发生InterruptedException异常。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值