Java 多线程编程

多线程在软件开发中用得很多,现在几乎所有的软件都用到了多线程,如:QQ、迅雷、eclipe集成开发环境等。

什么是多线程?

当一个程序启动后就是一个进程,可以理解进程就是CPU的一个执行流程,而多线程就是在一个进程内执行多个线程,相当于在一个执行流程内开辟多个

执行序列,举个例子:一个服务员每天要做端菜、洗碗、拖地等事情,每件事情可以理解为一个执行流程,让他开始洗碗那么他必须要把碗洗完了才能做其他的事情(流程),这样效率就很低,如果在他正在洗碗的时候能够做其它事情那么就很高效了,如他正在洗碗,这时让他去端菜,那就暂时停止洗碗去端菜,菜端完了继续洗碗。

 

时间片:

简单理解就是分配给线程的执行时间,实际上线程在微观上是串行执行的,也就是一个个执行,但是系统给每个线程都分配的执行时间,

如:

线程1 分配10ms的执行时间

线程2 分配10ms的执行时间

由于时间很短给人的感觉就是多个线程在一起执行。

 

线程的生命周期:

一个线程从创建、启动、结束有几种状态。

1.新建   线程已经准备就绪还没启动

2.运行 线程正在执行(在分配的时间内)

3.阻塞  线程已经启动但没有获得执行时间而处于等待队列中

4.结束 线程已经执行完毕并释放相关资源

 

Java实现多线程的3种方式:

1.让一个需要实现线程操作的类继承至Thread类,并重写父类的run方法

2.让一个需要实现线程操作的类实现Runnable接口

3.使用Timer和TimerTask组合

 

第一种实现方法:

package mypackage;
/**
 * 继承至Thread类使能够执行线程
 * @author dream
 *
 */
public class MyThread extends Thread
{
	
	
	public static void main(String[] args)
	{
		MyThread myth=new MyThread();
		myth.start();
		System.out.println("主线程");
	}
	
	
	
	//线程的调用run方法执行
	public void run()
	{
		int n=10;
		while(true)
		{
			if(n>0)
			{
				try
				{
					System.out.println(n);
					n--;
					Thread.sleep(1000);
				}
				catch(Exception ex)
				{
					
				}
			}
		}
	}
}


第二种实现方法:

package mypackage;

/**
 * 实现Runnable接口执行线程操作
 * @author dream
 *
 */
public class MyThread1 implements Runnable
{
	public static void main(String[] args)
	{
		MyThread myth=new MyThread();
		myth.start();
		System.out.println("主线程");
	}
	public void run()
	{
		int n=10;
		while(true)
		{
			if(n>0)
			{
				try
				{
					System.out.println(n);
					n--;
					Thread.sleep(1000);
				}
				catch(Exception ex)
				{
					
				}
			}
		}
	}
}


第三种实现方法:

package mypackage;

import java.util.Timer;
import java.util.TimerTask;

public class MyThread2 extends TimerTask
{
	public static void main(String[] args)
	{
		MyThread2 myth=new MyThread2();
		Timer timer=new Timer();
		timer.schedule(myth, 0);//启动线程
		System.out.println("主线程");
	}
	
	public void run()
	{
		int n=10;
		while(true)
		{
			if(n>0)
			{
				try
				{
					System.out.println(n);
					n--;
					Thread.sleep(1000);
				}
				catch(Exception ex)
				{
					
				}
			}
		}
	}
}


多线程遇到的问题及处理:

多线程虽然能够使软件高效运行,但用得不好会带来负面效果

如一个变量a=10,同时启动3个线程来读取它的值,每读取一次则值减一,这就有一个问题,3个线程在各自的时间段里执行,但操作的变量a是共有的

线程1 使a的值减一 正常情况应该a=9了,如果线程2已经使a减一了那么这就会出问题了。

下面是一段有问题的代码:

//---------threaddemo.java
package mypackage;

public class threaddemo
{
	public int money=20;
}

//OpeatorMoney.java
package mypackage;

public class OpeatorMoney extends Thread
{
   threaddemo demo;
   private String threadname;
   public OpeatorMoney(threaddemo demo1,String name)
   {
	   this.demo=demo1;
	   this.threadname=name;
   }
   public void run()
   {
	   while(true)
	   {
		   try
		   {
			   if(demo.money>0)
			   {
				   System.out.println("线程:"+this.threadname+"---"+demo.money);
				   demo.money--;
				   
			   }
			   else
			   {
				   break;
			   }
		   }
		   catch(Exception ex){}
	   }
   }
}

//ThreadTest.java
package demo1;

import java.util.Timer;

import mypackage.*;

public class ThreadTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{

		
		threaddemo demo=new threaddemo();
		OpeatorMoney opm1=new OpeatorMoney(demo, "线程1");
		OpeatorMoney opm2=new OpeatorMoney(demo, "线程2");
		OpeatorMoney opm3=new OpeatorMoney(demo, "线程3");
		
		opm1.start();
		opm2.start();
		opm3.start();
		
		
		
	}
	
	private static void Show(String msg)
	{
		System.out.println(msg);
	}

}


这段代码会输出:

线程:线程1---20
线程:线程2---20
线程:线程2---19
线程:线程1---18
线程:线程1---16
线程:线程1---15
线程:线程1---14
线程:线程1---13
线程:线程1---12
线程:线程1---11
线程:线程1---10
线程:线程1---9
线程:线程1---8
线程:线程1---7
线程:线程1---6
线程:线程1---5
线程:线程1---4
线程:线程1---3
线程:线程1---2
线程:线程1---1
线程:线程3---17
线程:线程2---17

这显然是有问题的,可以通过互斥解决这个问题,也就是当一个线程正在操作这个代码的时候其它线程必须等待:

一个案例代码:

//----Account.java
package mypackage;

/**
 * 模拟银行帐号的类
 * @author dream
 *
 */
public class Account 
{
	int money=0;//账户余额
	
	//取钱
	public synchronized void GetMoney()
	{
		System.out.println("准备取钱....");
		try
		{
			//检查是否有钱
			if(this.money==0)
			{
				wait();//账户没钱等待家长存钱
			}
			
			money=money-50;
			System.out.println("剩余:"+this.money);
			notify();//通知家长存钱
		}
		catch(Exception ex){}
	}
	
	//存钱
	public synchronized void SetMoney()
	{
		try
		{
			System.out.println("准备取钱....");
			if(this.money!=0)
			{
				wait();//如果孩子账户还有钱,则等待
			}
			
			money=200;
			System.out.println("存入"+this.money);
			notify();//通知孩子取钱
			
		}
		catch(Exception ex){}
	}
}

//----Parent.java
package mypackage;

/**
 * 模拟家长的类
 * @author dream
 *
 */
public class Parent extends Thread
{
	private Account account;
	
	public Parent(Account a)
	{
		this.account=a;
		start();
	}
	
	public void run()
	{
		try
		{
			while(true)
			{
				Thread.sleep(10000);
				this.account.SetMoney();
			}
		}
		catch(Exception ex){}
	}
}

//-----ThreadTest.java
package demo1;
import java.util.Timer;
import mypackage.*;

public class ThreadTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) 
	{

		Account a=new Account();
		Parent p1=new Parent(a);
		Student stu1=new Student(a);

	}
	
	private static void Show(String msg)
	{
		System.out.println(msg);
	}

}


 

输出:

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值