java基础-JAVA之多线程

来源:互联网 发布:文档网络在哪里 编辑:程序博客网 时间:2024/06/05 09:33

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

要想了解线程,先了解进程的概念进程:

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

1、线程的概念:

线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行;一个进程中至少有一个线程。

java中要想实现多线程,有两种手段,

一种是继续Thread类,另外一种是实现Runable接口。

通过继承Thread类来创建线程的方法。类Thread1声明为Thread的子类,它的构造方法定义线程名和起始参数。 

程序如下:

public class Thread1 extends Thread {      int k=0;      public Thread1(String name,int k)     {           super(name);                    this.k = k;     }             public void run()                        //覆盖run方法的线程体             int i = k;            System.out.println();            System.out.print(getName()+":  ");         while (i<50)         {             System.out.print(i+"  ");                         i+=2;         }              System.out.println(getName() +"  end!");     }               public static void main (String args[])     {             Thread1 t1 = new Thread1("Thread1",1);     //创建线程对象                     Thread1 t2 = new Thread1("Thread2",2);               t1.start();                                //启动执行线程                    t2.start();              System.out.println("activeCount="+t2.activeCount());     } }

2、创建线程的步骤: 

      1.定义一个类实现Runnable接口,重写接口中的run()方法。在run()方法中加入具体的任务代码或处理逻辑。 

       2.创建Runnable接口实现类的对象。 

       3.创建一个Thread类的对象,需要封装前面Runnable接口实现类的对象。(接口可以实现多继承) 

       4.调用Thread对象的start()方法,启动线程 

public class Thread1 extends Thread {    int k=0;    public Thread1(String name,int k)    {      super(name);      this.k = k;   }  public void run()  }
3、线程的四种状态:

 

新状态: 一个新产生的线程从新状态开始了它的生命周期。它保持这个状态知道程序start这个线程。

运行状态:当一个新状态的线程被start以后,线程就变成可运行状态,一个线程在此状态下被认为是开始执行其任务

就绪状态:当一个线程等待另外一个线程执行一个任务的时候,该线程就进入就绪状态。当另一个线程给就绪状态的线程发送信号时,该线程才重新切换到运行状态。

休眠状态: 由于一个线程的时间片用完了,该线程从运行状态进入休眠状态。当时间间隔到期或者等待的时间发生了,该状态的线程切换到运行状态。

终止状态: 一个运行状态的线程完成任务或者其他终止条件发生,该线程就切换到终止状态。

4、线程的使用:

4.1、创建一个线程,最简单的方法是创建一个实现Runnable接口的类一个创建线程并开始让它执行的实例:

// 创建一个新的线程class NewThread implements Runnable {   Thread t;   NewThread() {      // 创建第二个新线程      t = new Thread(this, "Demo Thread");      System.out.println("Child thread: " + t);      t.start(); // 开始线程   }     // 第二个线程入口   public void run() {      try {         for(int i = 5; i > 0; i--) {            System.out.println("Child Thread: " + i);            // 暂停线程            Thread.sleep(50);         }     } catch (InterruptedException e) {         System.out.println("Child interrupted.");     }     System.out.println("Exiting child thread.");   }} public class ThreadDemo {   public static void main(String args[]) {      new NewThread(); // 创建一个新线程      try {         for(int i = 5; i > 0; i--) {           System.out.println("Main Thread: " + i);           Thread.sleep(100);         }      } catch (InterruptedException e) {         System.out.println("Main thread interrupted.");      }      System.out.println("Main thread exiting.");   }}
运行结果如下:

Child thread: Thread[Demo Thread,5,main]Main Thread: 5Child Thread: 5Child Thread: 4Main Thread: 4Child Thread: 3Child Thread: 2Main Thread: 3Child Thread: 1Exiting child thread.Main Thread: 2Main Thread: 1Main thread exiting.

4.2、通过继承Thread来创建线程:

创建一个线程的第二种方法是创建一个新的类,该类继承Thread类,然后创建一个该类的实例。

继承类必须重写run()方法,该方法是新线程的入口点。它也必须调用start()方法才能执行。

// 通过继承 Thread 创建线程class NewThread extends Thread {   NewThread() {      // 创建第二个新线程      super("Demo Thread");      System.out.println("Child thread: " + this);      start(); // 开始线程   }    // 第二个线程入口   public void run() {      try {         for(int i = 5; i > 0; i--) {            System.out.println("Child Thread: " + i);                            // 让线程休眠一会            Thread.sleep(50);         }      } catch (InterruptedException e) {         System.out.println("Child interrupted.");      }      System.out.println("Exiting child thread.");   }} public class ExtendThread {   public static void main(String args[]) {      new NewThread(); // 创建一个新线程      try {         for(int i = 5; i > 0; i--) {            System.out.println("Main Thread: " + i);            Thread.sleep(100);         }      } catch (InterruptedException e) {         System.out.println("Main thread interrupted.");      }      System.out.println("Main thread exiting.");   }}

编译以上程序运行结果如下:

Child thread: Thread[Demo Thread,5,main]Main Thread: 5Child Thread: 5Child Thread: 4Main Thread: 4Child Thread: 3Child Thread: 2Main Thread: 3Child Thread: 1Exiting child thread.Main Thread: 2Main Thread: 1Main thread exiting.
5、多线程

有效利用多线程的关键是理解程序是并发执行而不是串行执行的。例如:程序中有两个子系统需要并发执行,这时候就需要利用多线程编程。

通过对多线程的使用,可以编写出非常高效的程序。不过请注意,如果创建太多的线程,程序执行的效率实际上是降低了,而不是提升了。

其中上下文的切换开销也很重要,如果创建了太多的线程,CPU花费在上下文的切换的时间将多于执行程序的时间!

// 文件名 : DisplayMessage.java// 通过实现 Runnable 接口创建线程public class DisplayMessage implements Runnable{   private String message;   public DisplayMessage(String message)   {      this.message = message;   }   public void run()   {      while(true)      {         System.out.println(message);      }   }}// 文件名 : GuessANumber.java// 通过继承 Thread 类创建线程public class GuessANumber extends Thread{   private int number;   public GuessANumber(int number)   {      this.number = number;   }   public void run()   {      int counter = 0;      int guess = 0;      do      {          guess = (int) (Math.random() * 100 + 1);          System.out.println(this.getName()                       + " guesses " + guess);          counter++;      }while(guess != number);      System.out.println("** Correct! " + this.getName()                       + " in " + counter + " guesses.**");   }}// 文件名 : ThreadClassDemo.javapublic class ThreadClassDemo{   public static void main(String [] args)   {      Runnable hello = new DisplayMessage("Hello");      Thread thread1 = new Thread(hello);      thread1.setDaemon(true);      thread1.setName("hello");      System.out.println("Starting hello thread...");      thread1.start();           Runnable bye = new DisplayMessage("Goodbye");      Thread thread2 = new Thread(bye);      thread2.setPriority(Thread.MIN_PRIORITY);      thread2.setDaemon(true);      System.out.println("Starting goodbye thread...");      thread2.start();       System.out.println("Starting thread3...");      Thread thread3 = new GuessANumber(27);      thread3.start();      try      {         thread3.join();      }catch(InterruptedException e)      {         System.out.println("Thread interrupted.");      }      System.out.println("Starting thread4...");      Thread thread4 = new GuessANumber(75);                thread4.start();      System.out.println("main() is ending...");   }}

运行结果如下,每一次运行的结果都不一样。

Starting hello thread...Starting goodbye thread...HelloHelloHelloHelloHelloHelloHelloHelloHelloThread-2 guesses 27Hello** Correct! Thread-2 in 102 guesses.**HelloStarting thread4...HelloHello..........remaining result produced.


6、synchronized:

格式:
synchronized(对象)
{
需要同步的代码;
}

格式:
在函数上加上synchronized修饰符即可。


同步可以解决安全问题的根本原因就在那个对象上。
该对象如同锁的功能。

6.1、同步特点: 

前提:多个线程 

解决问题注意:多个线程使用的是同一个锁对象

6.2、同步好处: 

同步解决了多线程的安全问题

6.3、同步的弊端: 

当线程很多时,因为每个线程都会去判断同步上的锁,很消耗资源,降低程序的运行效率





 


0 0