`
Yinny
  • 浏览: 295730 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

多线程重要方法的使用

 
阅读更多
  首先讲一下进程和线程的区别:

    进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。

    线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。

    线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。

    多进程是指操作系统能同时运行多个任务(程序)。

    多线程是指在同一程序中有多个顺序流在执行。

  在java中创建一个线程有两种方法:

    ①实现java.lang.Runnable接口,重写run()方法,启动:new Thread(this).start()。



package com.taobao.tina.test;

/**
 * @author Tina
 *
 */
public class ThreadTest1 {
	
	    public static void main(String[] args) {
	        Runnable1 r = new Runnable1();
	        //r.run();并不是线程开启,而是简单的方法调用
	        Thread t = new Thread(r);//创建线程
	        //t.run(); //如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
	        t.start(); //线程开启
	        for (int i = 0; i < 100; i++) {
	            System.out.println("main:"+i);
	        }
	    }
	}
	class Runnable1 implements Runnable{
	    public void run() {
	        for (int i = 0; i < 100; i++) {
	            System.out.println("Thread-----:"+i);
	        }
	    }
	}


 要注意的是:

    1.r.run()并不是启动线程,而是简单的方法调用。

    2.Thread也有run()方法,如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。

    3.并不是一启动线程(调用start()方法)就执行这个线程,而是进入就绪状态,什么时候运行要看CUP。

    ②继承java.lang.Thread类,重写run()方法。


package com.taobao.tina.test;

/**
 * @author Tina
 *
 */
public class ThreadTest2 {
    public static void main(String[] args) {
        Thread1 t = new Thread1();
        //t.run(); //这里也不能直接调用方法
        t.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("main:"+i);
        }
    }
}

//尽量使用实现Runnnable接口,因为接口比较灵活
class Thread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("Thread-----:"+i);
        }
    }
  }



虽然两种方法都可行,但是最好还是用第一种方法,因为使用接口灵活性好,java中时单继承、多实现。

Thread类中常用的方法有:

  ①sleep(long millis): 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。


package com.taobao.tina.test;

import java.util.Date;

/**
 * @author Tina
 *
 */
public class SleepTest {
	
	 public static void main(String[] args) {
	        Thread2 t = new Thread2();
	        t.start();
	        try {
	            Thread.sleep(10000); //主线程睡眠10秒钟
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
	        //主线程睡眠10秒钟后结束t线程
	        //t.interrupt(); //这种结束方式比较粗暴,如果t线程打开了某个资源还没来得及关闭也就是run方法还没有执行完就强制结束线程,会导致资源无法关闭
	        //t.stop();也是结束某个线程,这种方式比interrupt()更粗暴
	        t.flag = false;
	    }
	}
	class Thread2 extends Thread{
	    boolean flag = true; //用这种方式结束线程很不错,用一个变量控制run方法什么时候不再执行,不会出现run方法没有执行完毕就结束
	    @Override
	    public void run() { //run方法一结束,整个线程就终止了
	        while(flag){
	            System.out.println("---"+new Date()+"---");
	            try {
	                sleep(1000);
	            } catch (InterruptedException e) {
	                return;
	            }
	        }
	    }

}



package com.taobao.tina.test;

import java.util.Date;

/**
 * @author Tina
 *
 */
public class SleepTest {
	
	 public static void main(String[] args) {
	        Thread2 t = new Thread2();
	        t.start();
	        try {
	            Thread.sleep(10000); //主线程睡眠10秒钟
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
	        //主线程睡眠10秒钟后结束t线程
	        //t.interrupt(); //这种结束方式比较粗暴,如果t线程打开了某个资源还没来得及关闭也就是run方法还没有执行完就强制结束线程,会导致资源无法关闭
	        //t.stop();也是结束某个线程,这种方式比interrupt()更粗暴
	        t.flag = false;
	    }
	}
	class Thread2 extends Thread{
	    boolean flag = true; //用这种方式结束线程很不错,用一个变量控制run方法什么时候不再执行,不会出现run方法没有执行完毕就结束
	    @Override
	    public void run() { //run方法一结束,整个线程就终止了
	        while(flag){
	            System.out.println("---"+new Date()+"---");
	            try {
	                sleep(1000);
	            } catch (InterruptedException e) {
	                return;
	            }
	        }
	    }

}

②join():指等待t线程终止。也可以理解为将t线程合并到当前线程来,等待t线程结束后再往下执行。相当于方法调用
package com.taobao.tina.test;

/**
 * @author Tina
 *
 */
public class TestJoin {

    public static void main(String[] args) {
        Thread t = new Thread3("abc");
        t.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("我是tina线程");
            if(i==5){
                try {
                    t.join();
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Thread3 extends Thread{
    public Thread3(String s) { //给该线程取一个名字,用getName()方法可以去到该名字
        super(s);
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("我是"+getName()+"线程");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}


运行该程序结果为:
我是main线程
我是tina线程
我是main线程
我是tina线程
我是main线程
我是tina线程
我是tina线程
我是main线程
我是tina线程
我是main线程
我是tina线程
我是main线程
我是tina线程
我是tina线程
我是tina线程
我是tina线程
我是main线程
我是main线程
我是main线程
我是main线程


可以看到从第22行起就开始顺序执行了,因为i=10的时候就将该形成合并了。


  ③yield():暂停当前正在执行的线程对象,并执行其他线程。

  ④setPriority(): 更改线程的优先级。

    MIN_PRIORITY = 1
       NORM_PRIORITY = 5
           MAX_PRIORITY = 10


package com.taobao.tina.test;

/**
 * @author Tina
 * 
 */
public class YieldTest extends Thread{
	public YieldTest(){
		
	}
	public YieldTest(String name){
		super(name);
	}
	@Override
	public void run() {
         for(int i=0;i<=50;i++){
           System.out.println(""+this.getName()+"-----"+i);
           if(i==30){
           this.yield();
           System.out.println("I am "+this.getName()+"----"+i);//(1)
          }
	 }
	}
	public static void main(String[] args) {
	  YieldTest yt1=new YieldTest("max");  //优先级高不代表占用所有cpu时间
	  YieldTest yt2=new YieldTest("min");
          yt1.setPriority(Thread.MAX_PRIORITY); //(2)
          yt1.start();
          yt2.setPriority(Thread.MIN_PRIORITY); //(3)
          yt2.start();
	}
}


当代码中(2)(3)处都注释掉之后,yt1,yt2是一样的等级,这时候其实看不出在i=30的时候有什么区别。


没有(2)(3)条注释的情况下:多次运行会发现yt1这个进程抢cpu的技术比较高,每次都先完成。
max-----26
max-----27
max-----28
max-----29
max-----30
I am max----30
max-----31
max-----32
max-----33
max-----34

但是也有可能是yt2先执行到30,多次执行的结果我就不贴图了,因为yield()方法只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行了!

yield相对难理解一些,我在网上看到一个很形象的比喻:“就是说当一个线程使用了这个方法之后,他就把自己的cpu时间让掉,让自己或者其他的线程运行。就好像说这个线程轮到他上厕所了,然后他说“我要和大家来个竞赛',然后所有的人在同一起跑线冲向厕所。。。。有可能是别人进去了,也有可能他自己有抢到了。我们还知道线程有个优先级的问题,那么手里有优先权的这些人就一定能抢到厕所的位置吗? 不一定的,他们只是概率上大些,也有可能没特权的抢到了。” 借此就能很好地理解yield了。


  ⑤interrupt():中断某个线程,这种结束方式比较粗暴,如果t线程打开了某个资源还没来得及关闭也就是run方法还没有执行完就强制结束线程,会导致资源无法关闭

  要想结束进程最好的办法就是用sleep()函数的例子程序里那样,在线程类里面用以个boolean型变量来控制run()方法什么时候结束,run()方法一结束,该线程也就结束了。

  ⑥还有很多的方法就不一一列举了.........

  

  当然,多线程难点不在这些,多线程的难点在于多线程之间的协调。关于多线程的协调待续
分享到:
评论
3 楼 lvcesky 2015-09-25  
          
2 楼 囧囧有神 2013-09-22  
还有第三种创建线程方法: 实现callable接口
1 楼 囧囧有神 2013-09-22  
这么牛b,写这么多字

相关推荐

    java项目史上最简单的多线程使用方法(demo)

    本文将深入探讨Java项目中最简单的多线程使用方法,通过一个名为"thread-test"的示例项目来讲解如何在企业实际场景中应用多线程。 一、Java多线程基础 1. **Thread类与Runnable接口** Java中实现多线程有两种方式...

    C# Timer的多线程使用方法

    总结来说,C#的Timer类提供了灵活的方式来实现在多线程环境下的定时任务,理解它们的工作原理和使用方式对于编写高效、可靠的后台服务或UI交互至关重要。通过实践,你可以更好地掌握这些知识,并在你的项目中...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例),可直接运行

    2. **线程同步与互斥**:在多线程环境中,确保数据的一致性和完整性至关重要。线程同步可以通过`Mutex`、`Monitor`、`Semaphore`、`ReaderWriterLockSlim`等工具实现。例如,`Mutex`可以实现全局资源的独占访问,...

    QT多线程moveToThread使用方式

    `moveToThread`函数是QT多线程编程中的一个重要方法,它允许我们将一个对象移动到指定的QThread对象中,从而使该对象的工作在新的线程上下文中执行。 首先,理解多线程的基本概念至关重要。在计算机科学中,线程是...

    3种多线程实现同步方法

    在编程领域,多线程是实现并发执行任务的重要机制,特别是在多核处理器系统中,它能有效利用系统资源,提高程序的执行效率。然而,多线程也带来了数据同步的问题,因为多个线程可能同时访问共享资源,如果不加以控制...

    大漠多线程模板_大漠_大漠多线程_

    在IT行业中,多线程是程序设计中的一个重要概念,特别是在C#编程中。"大漠多线程模板"是一个专门针对C#开发的多线程处理框架,它为开发者提供了便捷的方式来管理和优化多线程应用。这个框架由知名开发者"大漠"创建,...

    java多线程之赛马程序实验8多线程练习下载进度

    总结来说,这个实验旨在帮助开发者深入理解Java多线程的概念,熟练运用`Thread`类的`run`和`start`方法,以及如何通过进度条来实时展示多线程任务的执行进度。通过实践,开发者可以更好地掌握并发编程的技巧,这对于...

    多线程使用原因以及例程

    ### 多线程使用原因及关键技术点解析 #### 一、多线程基本概念与目的 多线程技术是现代编程中的一项重要技术,尤其是在Java这样的面向对象语言中更是广泛应用。多线程能够显著提高程序的执行效率和响应速度,尤其...

    多线程编程示例

    总的来说,多线程编程是提升软件性能和响应能力的重要手段,学习如何有效利用多线程,不仅可以提高程序的并发性,还能解决复杂的问题,如异步I/O、并行计算等。通过不断实践和学习,你将在多线程的世界里游刃有余。

    多线程与多核编程方法

    "多线程与多核编程方法" 多线程与多核编程是当前计算机科学技术中一个非常重要的话题。在现代计算机系统中,多任务操作系统可以同时运行多个程序,是通过 CPU 分时和程序并发实现的。在这种情况下,进程和线程作为...

    C#多线程 C#多线程

    总结来说,C#中的多线程和线程池是提高程序并发性和性能的重要工具。通过使用`ThreadPool`,开发者可以更高效地利用系统资源,同时保持程序的响应性。在实际应用中,合理地设计和使用多线程能够显著提升计算密集型或...

    WinForm C# 多线程编程并更新界面(UI)

    在 WinForm 中,使用 C# 实现多线程编程并更新界面(UI)是非常重要的。我们可以使用 `Thread` 类来创建新的线程,并使用 `Invoke` 方法来更新界面。同时,我们需要确保线程安全,避免其他线程访问控件的成员。 ...

    java 多线程同步方法的实例

    在Java编程语言中,多线程同步是一种控制多个线程并发执行的重要机制,它确保了共享资源的安全访问,防止数据不一致性和竞态条件的发生。本文将深入探讨Java中的多线程同步方法,并通过实例来阐述其工作原理。 首先...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例)(201903)

    本资源“C#.NET多线程实例6个”显然是一份详细的教程,涵盖了多线程的基本使用到更高级的互斥概念,这对于理解和实践C#中的并发编程至关重要。 1. **多线程基本使用**:在C#中,创建和管理线程主要通过`System....

    C#多线程执行

    在多线程环境中,数据安全是个重要问题。C#提供了一些同步机制,如Mutex、Semaphore、Monitor和锁(lock关键字),来确保对共享资源的访问是线程安全的。例如,使用lock关键字可以防止数据竞争: ```csharp lock ...

    C#多线程互斥实例 多线程获取同一变量

    在编程领域,多线程是实现并发执行任务的重要机制,特别是在现代计算机系统中,多核处理器使得多线程成为提高程序性能的关键手段。C#语言提供了丰富的多线程支持,让我们能够编写出高效的多线程应用程序。在这个"多...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例).rar

    这个压缩包包含六个C#.NET多线程的实例,涵盖了多线程的基本使用以及互斥等高级特性。以下是这些实例可能涉及的知识点详解: 1. **线程创建与启动** - `System.Threading.Thread` 类是.NET中创建新线程的基础,...

    pb9多线程控件,能够真实实现多线程

    5. 示例代码的重要性:提供的示例可以帮助开发者理解如何在PB9中正确地使用多线程控件。 6. 移植问题:从PB11.5到PB9.0的移植可能需要解决兼容性问题,确保代码能在新环境中正常运行。 7. 不完善的解决方案:尽管该...

    JAVA多线程操作方法实用大全

    本文将深入探讨Java中的多线程操作方法,包括线程控制的基本方法、中断和睡眠以及相关示例。 首先,了解线程的基本状态至关重要。线程在运行过程中可能处于新建、可运行、运行、阻塞或死亡等状态。`isAlive()`方法...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例)_26.rar

    本资源“C#.NET多线程实例6个”涵盖了多线程的基本使用以及更高级的概念,如线程互斥,这将帮助开发者深入理解并有效地应用多线程技术。 1. **多线程基本使用**:在C#中,创建和管理线程主要通过`System.Threading`...

Global site tag (gtag.js) - Google Analytics