欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

java 多线程,

来源: javaer 分享于  点击 12817 次 点评:131

java 多线程,


java 多线程

标签(空格分隔): 线程 进程


  • java 多线程
      • 线程
        • 线程与进程的区别
        • Java线程
      • 线程的创建与开始
        • 线程的创建
          • 扩展Thread类实现多线程
          • 实现Runnable接口的多线程
      • 线程状态间的转换
          • 线程的常用方法介绍

线程

线程是一个程序内部的顺序控制流,一个进程中通常有多个线程,线程不能单独存在,总是属于某一个进程。

线程与进程的区别

    - 每个进程都有独立的代码和数据空间(进程上下文),进程间切换会有较大的系统开销。
    - 线程可以看作是轻量级进程,同一类线程共享这个进程中的代码和数据空间,而每个线程有独立的运行栈和程序计数器,线程间的切换开销小
    - 多进程是指操作系统中能同时执行多个程序、任务
    - 在同一个程序执行中,有多个顺序流同时执行

Java线程

    - java.lang.Thread类的一个实例
    - 每个线程都是通过某个特定的Tread对象所对应的run()方法来完成操作的,改方法被称为线程体
    - 通过Tread的start()方法启动一个线程
    - java中每个线程都有一个调用栈
    - 一个Java应用总是从main()方法开始运行,mian()方法运行在一个线程内,它被称为主线程

线程的创建与开始

线程的创建

    - Thread类继承
    - 实现runnable接口
1.扩展Thread类实现多线程

范例:

/**
 * 
 */
package com.frankstar.Thread;

/**
 * @author frankstar
 * 用Thread类创建线程 实现run方法
 *
 */
public class ThreadImplement {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MyThread mt1 = new MyThread("frank");
        MyThread mt2 = new MyThread("star");
        mt1.start();//开辟新的进程
        mt2.start();
        for (int i = 0; i<= 10; i++) {
            System.out.println("mainMethod:" + i);
        }

    }

}
class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }
    //重写实现run方法
    public void run() {
        for (int i = 0; i <= 10; i++) {
            System.out.println(this.getName() + ":" + i);
        }

    }
}

//ouput:(每次执行的结果都可能不同)
frank:0
frank:1
mainMethod:0
mainMethod:1
mainMethod:2
mainMethod:3
mainMethod:4
mainMethod:5
mainMethod:6
mainMethod:7
mainMethod:8
mainMethod:9
mainMethod:10
frank:2
frank:3
frank:4
frank:5
frank:6
frank:7
frank:8
frank:9
frank:10
star:0
star:1
star:2
star:3
star:4
star:5
star:6
star:7
star:8
star:9
star:10
2.实现Runnable接口的多线程

范例:
首先定一个类RunnableImplement.java实现接口Runnable

/**
 * 
 */
package com.frankstar.Thread;

/**
 * @author frankstar
 * 实现接口Runnable
 */
public class RunnableImplement implements Runnable {
    private String name;

    public RunnableImplement(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i <= 5; i++) {
            System.out.println(this.getName() + ":" + i);
        }

    }


}

在定义一个主线程类MyRunnable.java,用于创建多线程

/**
 * 
 */
package com.frankstar.Thread;

/**
 * @author frankstar
 * 使用Runnable接口实现多线程
 */
public class MyRunnable {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        RunnableImplement ri1 = new RunnableImplement("frank");
        RunnableImplement ri2 = new RunnableImplement("star");

        Thread t1 = new Thread(ri1);
        Thread t2 = new Thread(ri2);

        t2.start();
        t1.start();
    }

}
//output:(每次执行的结果都可能不同)
star:0
frank:0
star:1
star:2
star:3
star:4
star:5
frank:1
frank:2
frank:3
frank:4
frank:5

在使用Runnable接口实现和继承Thread类实现这2种方式,应该优先使用用Runnable接口实现,因为接口的实现可以实现多个,而类的继承只能是单继承。

线程状态间的转换

线程的整个生命流程:

Created with Raphaël 2.1.0线程状态间的转换创建创建就绪状态就绪状态运行状态运行状态阻塞状态阻塞状态start()调度阻塞事件阻塞解除

就绪状态:当线程有资格运行,但调度程序还没有把它选定为运行线程时线程所处的状态。当start()方法调用时,线程首先进入就绪状态。在线程运行之后或者从阻塞、等待或睡眠状态回来后,也返回到就绪状态。
运行状态:线程调度程序从就绪池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。
阻塞状态:这是线程有资格运行时它所处的状态。其特点是:线程仍旧是活的,但是当前没有条件运行。换句话说,它是可运行的,但是如果某件事件出现,他可能返回到可运行状态。

线程的常用方法介绍

sleep方法

/**
 * 
 */
package com.frankstar.Thread;

import java.util.Date;

/**
 * @author frankstar
 * 线程sleep方法
 */
public class ThreadSleep {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TestThread tt = new TestThread();
        tt.start();//调用start()方法启动新线程
        try {
            TestThread.sleep(10000);
            System.out.println("主线程睡眠10秒后启动");
            //由于sleep方法属于静态方法,可以使用"类名.静态方法名"或者"对象的引用.静态方法名"
            //在哪个线程中调用了sleep()方法就是让哪个线程睡眠
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        tt.flag = false;//改变循环条件,结束死循环

    }

}

class TestThread extends Thread {
    boolean flag = true;//控制循环的条件

    public void run() {
        while(flag) {
            System.out.println(new Date().toLocaleString());
            try {
                sleep(1000);//线程每隔一秒睡一次,然后再次启动该线程
            } catch (InterruptedException e) {
                return;
            }
        }
    }
}

join方法

/**
 * 
 */
package com.frankstar.Thread;

import java.util.Date;

/**
 * @author frankstar
 *
 */
public class ThreadJoin {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        TestJoinThread tjt = new TestJoinThread("frankstar");
        tjt.start();//启动
        try {
            tjt.join();//将子线程合并到主线程,合并线程后,程序的执行的过程就相当于是方法的调用的执行过程

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        for (int i = 0; i <= 5; i++) {
            System.out.println("I am mainThread!");
        }
    }

}

class TestJoinThread extends Thread {
    //构造方法
    public TestJoinThread(String name) {
        super(name);
    }

    public void run() {
        for (int i = 0; i <= 5; i++) {
            System.out.println("I am at " + getName() + " time at " + new Date().toLocaleString());

            try {
                sleep(1000);
            } catch (InterruptedException e) {
                return;
            }
        }
    }

}

yield方法

/**
 * 
 */
package com.frankstar.Thread;

/**
 * @author frankstar
 *
 */
public class ThreadYield {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TestYieldThread tyt1 = new TestYieldThread("frank");
        TestYieldThread tyt2 = new TestYieldThread("star");

        tyt1.start();
        tyt2.start();

        for (int i = 0; i <= 5; i++) {
            System.out.println("I am main Thread!");
        }

    }

}

class TestYieldThread extends Thread {
    //构造方法
    public TestYieldThread(String name) {
        super(name);
    }

    public void run() {
        for (int i = 0; i <= 5; i++) {
            System.out.println(getName() + ": " + i);
            if (i % 2 == 0) {
                yield();//当执行到i能被2整除时当前执行的线程就让出来让另一个在执行run()方法的线程来优先执行
            }
        }
    }
}

相关文章

    暂无相关文章
相关栏目:

用户点评