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);

 }

}

输出:

java for threading

Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.