您的位置:首页 > 职场人生

黑马程序员--Java基础--06多线程

2014-02-17 23:20 651 查看
----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

1.多线程概念及创建

进程:正在执行的程序,特性为:动态性,并发性,独立性。

线程:是进程中用于控制程序执行的控制单元(执行路径,执行情景)进程中至少有一个线程。

注:编程时,必须确保线程不会妨碍到统一进程的其他线程。

 

线程的使用步骤:

(1)定义一个线程

(2)创建线程实例

(3)启动线程

(4)终止线程

 

线程的定义

(1)继承Thread类。

步骤:

定义类继承Thread。

复写Thread类中的run方法。

目的:将自定义代码存储在run方法。让线程运行。

 

调用线程的start方法,

该方法两个作用:启动线程,调用run方法。

//创建类MyThread继承Thread
class MyThread extends Thread
{
public void run(){
//run方法里为线程启动后需要执行的代码
System.out.println("继承创建");
}
}

class TestThread
{
public static void main(String[] args)
{
//实例化线程对象
MyThread my = new MyThread();
//启动线程,start为初始化一个线程并执行run方法,如果为my.run()的话将不会建立线程
my.start();
}
}


(2)实现接口Runnable

步骤:

定义类实现Runnable接口

覆盖Runnable接口中的run方法。

将线程要运行的代码存放在该run方法中。

通过Thread类建立线程对象。

将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

为什么要将Runnable接口的子类对象传递给Thread的构造函数。

因为,自定义的run方法所属的对象是Runnable接口的子类对象。

所以要让线程去指定指定对象的run方法。就必须明确该run方法所属对象。

调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

  //创建类MyRunnable实现接口Runnable
  class MyRunnable implements Runnable
  {
  	public void run(){
  		//run方法里为线程启动后需要执行的代码
  		System.out.println("实现接口创建");
  	}
  }
  
  class TestRunnable
  {
  	public static void main(String[] args)
  	{
  		//创建接口myb
  		MyRunnable myb = new MyRunnable();
  		//将myb作为参数传入Thread,实例化线程对象
  		Thread my = new Thread(myb);
  		//启动线程
  		my.start();
  	}
  }


2.线程状态,同步及安全

(1)线程的状态:被创建,可运行,阻塞,死亡。



(2)线程同步

如果一个资源被多个线程使用的话,不进行同步操作会造成读取严重错误,如果想让当前资源被一个线程使用时,不会受到其他线程影响,应该给当前资源上锁,java中使用sychronized关键字保证数据同步,格式为sychronized(指定收益的对象){同步代码块}

  //单例懒汉式
  class Single
  {
  	//定义本类对象
  	private static Single s = null;
  	//私有化构造方法
  	private Single(){}
  	public static  Single getInstance()
  	{
  		//将本类作为收益对象传入关键字,对象如同锁。持有锁的线程可以在同步中执行。
          //没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。
  			synchronized(Single.class)
  			{
  				//保证线程执行完此代码块
  				if(s==null)
  					s = new Single();
  			}
  		return s;
  	}
  }<
ada6
/span>


同步的前提:

必须要有两个或者两个以上的线程。

必须是多个线程使用同一个锁。

必须保证同步中只能有一个线程在运行。

 

  //死锁线程
  public class Dead {
  	public static void main(String[] args) {
  		new Thread(new Dead1(true)).start();//线程1
  		new Thread(new Dead1(false)).start();//线程2
  	}
  }
  
  class Dead1 implements Runnable {
  	// 定义静态对象使线程共享
  	static Object ob1 = new Object();
  	static Object ob2 = new Object();
  	// 定义标示
  	private boolean flag;
  
  	// 定义含标示的构造方法
  	Dead1(boolean flag) {
  		this.flag = flag;
  	}
  
  	public void run() {
  		if (flag) {
  			while (true) {
  				//同步中嵌套同步易发生死锁现象,当flag为真时运行下列代码,收益对象为ob1,
  				//但当代码到此进入冻结状态释放运行权限给线程2时,收益对象为ob2,同时代码
  				//进入冻结状态释放运行权后,线程1所需收益对象ob2还在线程2中无法释放,而
  				//线程2也需收益对象ob1以便运行后续代码,因此线程进入死锁状态
  				synchronized (ob1) {
  					System.out.println("aaa..");
  					synchronized (ob2) {
  						System.out.println("bbb..");
  					}
  				}
  			}
  		}
  
  		else {
  			while (true) {
  				synchronized (ob2) {
  					System.out.println("ccc..");
  					synchronized (ob1) {
  						System.out.println("ddd..");
  					}
  				}
  			}
  		}
  	}
  }


线程示例:

生产消费者线程

class Res
{
//商品计数
private int sum;
//定义标示符操作生产者与消费者前后顺序
private boolean flag = false;
//Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。
//此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。
private Lock lock = new ReentrantLock();
//生成Condition对象,替换Object中的wait,notify notifyAll
Condition con_pro = lock.newCondition();
Condition con_con = lock.newCondition();

public void set()throws InterruptedException{
//上锁
lock.lock();
try{
while(flag)
//生产者冻结
con_pro.await();
//商品计数
this.sum++;
System.out.println(Thread.currentThread().getName()+"生产商品:"+sum);
this.flag = true;
//消费者进入可执行状态
con_con.signal();
}finally{
//解锁
lock.unlock();
}
}

public void out()throws InterruptedException{
//上锁
lock.lock();
try{
while(!flag)
//消费者冻结
con_con.await();
System.out.println(Thread.currentThread().getName()+"消费商品:"+sum);
this.flag = false;
//生产者进入可执行状态
con_pro.signal();
}finally{
//解锁
lock.unlock();
}
}
}
//生产者
class Produce implements Runnable
{
private Res res;
Produce(Res res){
this.res = res;
}
public void run(){
while(true){
try{
res.set();
}catch(Exception e){
}
}
}
}
//消费者
class Consumer implements Runnable
{
private Res res;
Consumer(Res res){
this.res = res;
}
public void run(){
while(true){
try{
res.out();
}catch(Exception e){
}
}
}
}

class Test3
{
public static void main(String[] args)
{
Res r = new Res();
Produce p = new Produce(r);
Consumer c = new Consumer(r);
//两个生产线同时生产
new Thread(p).start();
new Thread(p).start();
//两个消费者同时消费
new Thread(c).start();
new Thread(c).start();
}
  }


----------- android培训java培训、java学习型技术博客、期待与您交流! ------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: