多线程基础

Posted 分享博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程基础相关的知识,希望对你有一定的参考价值。

多线程基础(二)

1、创建线程

1)使用Thread创建并启动线程
– 通过继承Thread类并重写run方法来定义一个具体的线程。
run方法中定义线程要完成的任务。

package day04;
/**
 * 第一种创建线程的方法
 * 继承Thread类,重写run方法
 * run方法:定义线程要完成的任务
 * @author Administrator
 *
 */
public class ThreadDemo1 {

    public static void main(String[] args) {

        Thread t1=new MyThread1();
        Thread t2=new MyThread2();
        /**
         * start方法将线程纳入到线程调度,
         * 而不是不直接调run方法
         * 线程进入runnable状态,等待线程调度分配时间片段
         * 当线程调度将时间分配给当前线程的时候,该线程的run方法才会运行
         * 直到线程的run方法执行完毕,线程结束,
         * 最终被回收。
         * 在线程的run方法执行期间,该线程处于走走停停的状态
         */

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


    }

}
//创建MyThread1类继承Thread类
class MyThread1 extends Thread{
    //重写run方法
    public void run(){
        for(int i=0;i<1000;i++){
            System.out.println("你是谁?");
        }
    }
}
class MyThread2 extends Thread{
    public void run(){
        for(int i=0;i<1000;i++){
            System.out.println("我是查水表的");
        }
    }

}

2) 使用Runnable创建并启动线程
定义线程体Runnable
优点:
可以将线程与线程要执行的任务分离开减少耦合
同时java是单一继承,定义一个类实现Runnable接口
这样的做法可以更好的去实现其他父类或接口。
因为接口是多继承关系

package day04;
/**
 * 创建线程的第二种方法
 * 定义线程体Runnable
 * 优点:
 * 可以将线程与线程要执行的任务分离开减少耦合
 * 同时java是单一继承,定义一个类实现Runnable接口
 * 这样的做法可以更好的去实现其他父类或接口。
 * 因为接口是多继承关系
 * @author Administrator
 *
 */
public class ThreadDemo2 {

    public static void main(String[] args) {

        Runnable run1=new MyRunnable1();
        Runnable run2=new MyRunnable2();

        Thread t1=new Thread(run1);
        Thread t2=new Thread(run2);

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

}
class MyRunnable1 implements Runnable{
    public void run(){
        for(int i=0;i<1000;i++){
            System.out.println("你是谁");
        }
    }
}
class MyRunnable2 implements Runnable{
    public void run(){
        for(int i=0;i<1000;i++){
            System.out.println("我是修水管的!");
        }
    }
}

3)使用内部类创建线程
当一个线程只需要一个实例时

package day04;
/**
 * 使用匿名内部类的形式实现创建线程
 * 当一个线程只需要一个实例时
 * @author Administrator
 *
 */
public class ThreadDemo3 {

    public static void main(String[] args) {
         Thread t1=new Thread(){
             public void run(){
                 for(int i=0;i<1000;i++){
                     System.out.println("你是谁呀?");
                 }
             }
         };
        t1.start();

         Thread t2=new Thread(new Runnable(){
             public void run(){
                 for(int i=0;i<1000;i++){
                     System.out.println("我是查水表的");
                 }
             }
         });
         t2.start();
         //等价于上面的写法
         //Runnable runn=new Runnable();
         //Thread t2=new Thread(runn);
    }


}

2、线程操作API

  • Thread curreentThread()
    获取当前代码片段的线程
package day04;
/**
 * 获取当前代码片段的线程
 * Thread curreentThread()
 * 可以调用Thread提供的静态方法
 * @author Administrator
 *
 */

public class ThreadDemo4 {

    public static void main(String[] args) {
        //获取的就是main方法的线程 
        Thread t1=Thread.currentThread();
         System.out.println("调用main方法的线程是:"+t1);

         //创建一个线程
         Thread t2=new Thread(){
             public void run(){
                //获取当前线程
                 Thread myt=Thread.currentThread();
                System.out.println("自己创建的线程是:"+myt);
             }
         };
         t2.start();
         testCurrent();

    }
    public static void testCurrent(){

        Thread t=Thread.currentThread();

        System.out.println("调用testCurrent的线程是:"+t);

    }

}

3、获取线程信息

Thread提供了获取线程的相关方法:

–long getId(); 返回I线程的标识符

–String getName();返回线程的名称

–int getPriority();返回线程的优先级

–Thread.state getState();获取线程的状态

–boolean isAlive();测试线程是否或者

–boolean isDaemon();测试线程是否为守护线程

–boolean isInterrupted();测试线程是否中断

package day04;
/**
 * 线程其他API
 * @author Administrator
 *
 */
public class ThreadDemo {

    public static void main(String[] args) {
        //获取main方法的线程相关信息
        Thread t=Thread.currentThread();

        //获取线程Id
        long id=t.getId();
        System.out.println("id:"+id);

        /**
         * 获取线程的名字,通常由系统指定
         * 格式为:Thread-x
         * 但调用main方法的线程名字不是这个。
         */
        String name=t.getName();
        System.out.println("name:"+name);

        //获取线程的有限级别
        int p=t.getPriority();
        System.out.println("优先级:"+p);

        //获取线程的状态
        System.out.println("状态:"+t.getState());

        //获取线程是否或者
        System.out.println("alive:"+t.isAlive());

        //获取线程是否是后台线程
        System.out.println("daemon:"+t.isDaemon());

        //获取线程是否被中断
        System.out.println("是否中断:"+t.isInterrupted());


    }

}

4、线程优先级
线程的优先级分为10级,值为1-10,之中1最低,10最高,默认为5。

–Thread.MIN_PRIORITY 值为1

–Thread.MAX_PRIORITY 值为10

–Thread.NORMOR_PRIORITY 值为5

package day04;
/**
 * 线程优先级
 * 1-10;
 * 理论上,线程优先级高的线程,被分配的时间片段的次数多
 * @author Administrator
 *
 */
public class ThreadDemo6 {

    public static void main(String[] args) {
         Thread max=new Thread();
             for(int i=0;i<2000;i++){
                 System.out.println("max");
            }

             Thread min=new Thread();
             for(int i=0;i<2000;i++){
                 System.out.println("min");
            }

             Thread norm=new Thread();
             for(int i=0;i<2000;i++){
                 System.out.println("norm");
            }
             max.start();
             min.start();
             norm.start();
        max.setPriority(Thread.MAX_PRIORITY);
        min.setPriority(Thread.MIN_PRIORITY);
    }


}

5、守护线程

–void setDaemon(boolean)

–当参数为true时,该线程为守护线程
特点:当进程只剩下守护线程时,所有的守护线程强制终止。

6、sleep方法

–static void sleep(long ms)
该方法会使当前线程进入阻塞状态指定毫秒,当阻塞指定毫秒后,当前线程会重新进入Runnable状态,等待分配时间片。会抛出InterruptException,要捕获异常。

package day04;
/**
 * 后台线程,守护线程
 * 特点:
 * 当线程中所有的前台线程都结束时,后台线程结束,
 * 无论后台线程是否还在运行
 * 
 * sleep方法
 * 使当前线程进入一个阻塞状态
 * 线程停止运行
 * sleep(int ms)
 * sleep(1000)
 * @author Administrator
 *
 */
public class ThreadDemo7 {

    public static void main(String[] args) {
         //rose 扮演:前台线程
        Thread rose=new Thread(){
            public void run(){
                for(int i=0;i<10;i++){
                    System.out.println("rose:let me go!");
                }
                try {
                    Thread.sleep(1000);

                } catch (InterruptedException e) {

                }
                System.out.println("rose:AAAAAAAaaa");

                System.out.println("噗通");
            }
        };
        //joke 扮演者:后台线程
        Thread joke=new Thread(){
            public void run(){
                //死循环
                while(true){
                    for(int i=0;i<10;i++){
                    System.out.println("joke:you jump,i jump!");
                }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {

                    }
            }

        }
    };
        rose.start();
        //守护线程
        joke.setDaemon(true);
        joke.start();
    }
}

7、join方法

–void join()
用于等待当前线程结束,抛出异常InterruptException

package day04;
/**
 * join可以使线程同步
 * 
 * @author Administrator
 *
 */
public class ThreadDemo9 {
    //显示图片是否下载完毕
    public static   boolean isFinish;
    public static void main(String[] args) {
        //下载线程
        Thread download =new Thread(){
            public void run(){

                for(int i=0;i<=100;i++){
                    System.out.println("down:图片下载"+i+"%");;

                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {

                }
                System.out.println("图片下载完成!");
                isFinish=true;
            }
        };
        /**
         * main方法中定义一个内部类show,
         * 该内部类中若想引用main方法中的其他
         * 局部变量,那么这个变量必须是final的类型
         */
        //显示线程
        Thread show=new Thread(){
            public void run(){
                try {
                    //这里应该等待下载线程将图片加载完毕之后再执行
                    download.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                for(int i=0;i<=100;i++){
                    System.out.println("show:图片加载"+i+"%");
                    if(!isFinish){
                        throw new  RuntimeException("图片加载失败!");
                    }
                }
                System.out.println("图片显示完成!");
            }

        };
        download.start();
        show.start();
    }

}

8、线程小实例
实现电子表的功能

package day04;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 电子表
 * @author Administrator
 *
 */
public class ThreadDemo8 {

    public static void main(String[] args) {

        SimpleDateFormat sdf=new
                 SimpleDateFormat("HH:mm:ss");

         while(true){
             Date now=new Date();
             System.out.println(sdf.format(now));

             try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {

            }
         }
    }

}

如果您感觉我的文章对您有帮助,请帮忙点击下广告,以支持本站的发展,谢谢!
本文由【waitig】发表在等英博客 本文固定链接:多线程基础(二) Wordpress技术交流群:451350210
如果您觉得文章对您有帮助,可以在此赞助:

以上是关于多线程基础的主要内容,如果未能解决你的问题,请参考以下文章

线程学习知识点总结

号称史上最全Java多线程与并发面试题总结—基础篇

多个请求是多线程吗

java基础入门-多线程同步浅析-以银行转账为样例

python小白学习记录 多线程爬取ts片段

多线程编程