黑马程序员——多线程

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

< 今日心情 >!!

一、 概述

1.进程

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

2.线程

进程中的一个独立的控制单元。
线程在控制着进程的执行。

一个进程中至少有一线程。

注:线程可以看成是一条独立的生产线,开启一个线程可以独立运行其中的代码。

二、 创建线程

1.继承Thread类

覆盖父类中的run方法。
线程运行的代码放在run方法中。

创建线程

建立子类对象。

数据和线程不分离,每个线程中的数据独立,线程间数据不共享。

开启线程

调用start方法。

2.实现Runnable接口。

覆盖接口中的run方法。
创建子类对象。
创建线程
格式:
Thread t1=new Thread(Runnable子类对象);
数据和线程分离,创建线程接收对象,线程间数据共享。
开启线程
t1.start();

3.线程的5种状态


class TickThread extends Thread
{
	int con=100;//车站共有100张票
	public void run()
	{
		while(con>0)
			System.out.println("您的票是:"+con--);
	}
}
class ThreadDemo
{
	public static void main(String[] args) 
	{
		//创建两个窗口来售票
		TickThread t1=new TickThread();
		TickThread t2=new TickThread();
		t1.start();
		t2.start();
	}
}
class Tick implements Runnable
{
	int con=100;//车站共有100张票
	public void run()
	{
		while(con>0)
			System.out.println("您的票是:"+con--);
	}
}
class ThreadDemo
{
	public static void main(String[] args) 
	{
		//创建两个窗口来售票
		Tick t=new Tick();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		t1.start();
		t2.start();
	}
}




注:线程有自己的名字,可以通过构造函数,或者setName方法设置。currentThread方法获取当前线程对象,getName获取线程名字

三、线程安全

class TickThread implements Runnable
{
	int con=100;//车站共有100张票
	public void run()
	{
		while(con>0)
		{
			try
			{
				Thread.sleep(20);//手动延迟20毫秒
			}
			catch (Exception e)
			{
			}
			
			System.out.println("您的票是:"+con--);
		}
	}
}
class ThreadDemo
{
	public static void main(String[] args) 
	{
		//创建两个窗口来售票
		TickThread t=new TickThread();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		t1.start();
		t2.start();
	}
}

1.导致线程安全的原因

多个线程访问出现延迟;

线程随机性 。

注:

线程安全问题在理想状态下,不容易出现,但一旦出现对软件的影响是非常大 的。

2.同步(synchronized)

格式:

synchronized(对象)

{

//需要同步的代码

}

注:对象如同锁的功能,synchronized如同一个门。当多个synchronized持有同一个对象的时候,一旦有一个线程进入其中的一个synchronized区域,这些synchronized都会处于“锁上”的状态。

好比一楼二楼各有一个厕所,但是用了同一个电子锁,一旦有人进入其中的一个厕所,这两个门都会锁上。别人进不去,只能等着。

3.同步的特点

前提:
同步需要两个或者两个以上的线程;
多个线程使用的是同一个锁。
弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形 中会降低程序的运行效率。

4.同步函数

格式:

在函数上加上synchronized,位置在返回值类型前边。

同步函数用的锁是this。

class Tick
{
	private int con=100;
	public void put()
	{
		System.out.println(Thread.currentThread().getName()+":您的票是:"+con--);
	}
	public int getCon()
	{
	    return con;
	}
}
class TickThread implements Runnable
{
	Tick t=new Tick();
	public void run()
	{
		while(t.getCon()>0)
		{
			try
			{
				Thread.sleep(20);
			}
			catch (Exception e)
			{
			}
			synchronized(this)
			{
				if(t.getCon()>0)
					t.put();
			}
		}
	}
}
class ThreadDemo
{
	public static void main(String[] args) 
	{
		//创建两个窗口来售票
		TickThread t=new TickThread();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		t1.start();
		t2.start();
	}
}


5.线程间通信


其实线程间通信就是在对共享数据进行操作。

注意:
这些方法存在与同步中;
使用这些方法时必须要标识所属的同步的锁。
锁可以是任意对象,所以任意对象调用的方法一定定义Object类中。

wait()和sleep()的区别

wait():释放CPU执行权,释放锁。

sleep():释放CPU执行权,不释放锁。

class Sources
{
	int value=1;
	private boolean ck=true;
	
	public synchronized void set(int value)
	{
		while(!ck)
		{
			goWait();
		}
		this.value=value;
		System.out.println(Thread.currentThread().getName()+":输入:"+value);
		ck=false;
		this.notifyAll();
	}
	public synchronized int get()
	{
		while(ck)
		{
			goWait();
		}
		System.out.println(Thread.currentThread().getName()+":输出:"+value);
		ck=true;
		this.notifyAll();
		return value;
	}
	private void goWait()
	{
		try
		{
			this.wait();
		}
		catch (Exception e)
		{
		}
	}

}

class InPut implements Runnable
{
	private int i=0;
	private Sources s;
	public InPut(Sources s)
	{
		this.s=s;
	}
	public void run()
	{
		while(i<100)
		{
			s.set(i++);
		}
	}
}

class OutPut implements Runnable
{
	private Sources s;
	private int i=0;
	public OutPut(Sources s)
	{
		this.s=s;
	}
	public void run()
	{
		while(i<100)
		{
			i=s.get();
		}
	}
}

class  TongXinDemo
{
	public static void main(String[] args) 
	{
		Sources s=new Sources();
		InPut i=new InPut(s);
		OutPut o=new OutPut(s);

		Thread t1=new Thread(i);
		Thread t2=new Thread(i);
		Thread t3=new Thread(o);
		Thread t4=new Thread(o);

		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}

}

6.死锁

class DeadThread implements Runnable
{
	private int i=0;
	Object obj=new Object();
	public void run()
	{
		if(i++==0)
		{
			while(true)
			{
				synchronized(obj)
				{
					show();
				}
			}
		}
		else
		{
			while(true)
			{
				show();
			}
		}
	}
	public synchronized void show()
	{
		System.out.println(Thread.currentThread().getName()+"进入办公室……");
		synchronized(obj)
		{
			System.out.println(Thread.currentThread().getName()+"开始工作……\n");
		}
	}

}

class DeadThreadDemo 
{
	public static void main(String[] args) 
	{
		DeadThread d=new DeadThread();
		Thread t1=new Thread(d);
		Thread t2=new Thread(d);
		t1.start();
		t2.start();
	}
}


7.lock

jkd1.5中对同步的升级,将synchronize替换成了lock,将object中的wait,notify,notifyAll替换成立condition对象。
import java.util.concurrent.locks.*;
class Sources
{
	private	int value=0;
	private Lock lock=new ReentrantLock();
	Condition c1=lock.newCondition();
	Condition c2=lock.newCondition();
	private boolean isIn =true;
	public void set()
	{
		while(value <100)
		{
			lock.lock();
			try
			{
				while(!isIn)
				{
					c1.await();
				}
				value++;
				System.out.println(Thread.currentThread().getName()+":输入:"+value);
				isIn=false;
				c2.signal();
			}
			catch (Exception e)
			{
			}
			finally
			{
				lock.unlock();
			}
		}
	}
	public void get(int max)
	{
		int i=0;
		while(i
     
     



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值