javaSE-9-线程-Thread、Runnable

  • 多线程并发与单线程,效率多线程并不比单线程更快,只是我们感官上感觉多线程并发更快
  • 创建线程的两种方式:
    • 继承Thread类,重写run();方法,启动线程调用start();方法
    • 实现Runnable接口
  • 继承Thread类:
/**
 * 多线程:
 * 线程:一个顺序的单一的程序执行流程就是一个线程。代码一句一句的有先后顺序的执行。
 * 多线程:多个单一顺序执行的流程并发运行。造成“感官上同时运行的效果”
 *
 * 多个线程实际运行是走走停停的,线程调度程序会将CPU运行时间发分为若干个 时间片段 并尽可能
 * 均匀的分配给每个线程,拿到时间片的线程被CPU执行这段时间。
 * 当超时后线程调度程序会再次分配一个时间片段给一个线程使得CPU执行它。
 * 如此反复。由于CPU执行时间在纳秒级别,我们感觉不到切换线程运行的过程。
 * 所以微观上走走停停,宏观上感觉一起运行的线程称为并发运行!
 *
 *
 * 第一种创建线程的方式:
 * 定义一个类继承Thread,并重写run方法。在run方法中定义要与其线程并发运行的任务
 * 启动线程时要使用start方法!
 *
 * 继承:有一个问题,就是线程定义好了,就定义了并发干的事,
 * 线程和线程的任务绑定死了,局限
 */
public class ThreadDemo1 extends Thread {
    public static void main(String[] args) {
        Thread demo2 = new ThreadDemo2();
        Thread demo34 = new ThreadDemo34();
        //run()方法是干的活,是任务
        //启动线程用start()方法,调用线程,就不考虑先后调用的问题了
        demo2.start();
        demo34.start();
    }
}

/**
 * 第一种创建线程的方式优点在于结构简单,便于匿名内部类形式创建
 * 缺点:
 * 1、直接继承线程,会导致不能再继承其他类去复用方法,这在实际开发中非常不便
 * 2、定义线程的同时重写了run方法,会导致线程与线程任务绑定在了一起,不利于线程的重用
 *
 */
class ThreadDemo2 extends Thread{
    public void run(){
        for(int i=0;i<100;i++){
            System.out.println("你是谁");
        }
    }
}

class ThreadDemo34 extends Thread{
    public void run(){
        for(int i=0;i<100;i++){
            System.out.println("查水表的");
        }
    }
}
  • 实现Runnable接口:
/**
 * 第二种创建线程的方式
 * 实现Runnable 接口单独定义线程任务
 *
 * 单独去定义线程任务,不再是绑定线程任务了
 * 线程的重用,有线程任务后,只需要new
 */
public class ThreadDomo2 {
    public static void main(String[] args) {
        /**
         * 将线程任务,和创建线程分开了
         */
        //实例化线程任务
        Runnable run1 = new MyRunnable1();
        Runnable run2 = new MyRunnable2();
        //创建两个线程
        Thread thread1 = new Thread(run1);
        Thread thread2 = new Thread(run2);
        //启动线程
        thread1.start();
        thread2.start();

    }
}

class MyRunnable1 implements Runnable{

    public void run(){
        for(int i=0;i<100;i++){
            System.out.println("你是谁");
        }
    }
}
class MyRunnable2 implements Runnable{

    public void run(){
        for(int i=0;i<100;i++){
            System.out.println("is m");
        }
    }
}
  • 两种方式的匿名内部类创建线程
/**
 * 以匿名内部类的形式完成线程的两种创建方式
 */
public class ThreadDemo3 {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
               for(int i=0;i<50;i++){
                   System.out.println("你是谁");
               }
            }
        }.start();

      new Thread(new Runnable(){
            public  void run(){
                for(int i=0;i<50;i++){
                    System.out.println("急啊急啊");
                }
            }
        }).start();

      Runnable run = ()-> System.out.println("123");
    }
}
  • main方法是主线程,可以获取线程的名字
/**
 * java中所有的代码都是靠线程运行的,main方法也不例外
 * java程序开始运行时,JVM会创建一条线程来执行main方法。这条运行main方法的线程的名字
 * 叫做main,也称他为主线程
 *
 * 线程提供了一个静态方法,可以获取到运行该方法的线程
 * static Thread currentThread()
 *
 * 调用start方法CPU才会分配时间片
 */
public class ThreadDemo4 {
    public static void main(String[] args) {
        Thread thread = Thread.currentThread();
        System.out.println("main线程是:"+thread);//main线程是:Thread[main,5,main]
        dosome();//dosome方法线程是:Thread[main,5,main]

        System.out.println("main方法执行完毕");

        Thread thread1 = new Thread(){
          public void run(){
              Thread p = Thread.currentThread();
              System.out.println("自定义线程"+p+"开始执行");//自定义线程Thread[Thread-0,5,main]开始执行
              dosome();//dosome方法线程是:Thread[Thread-0,5,main]
              System.out.println("自定义线程"+p+"执行结束");//自定义线程Thread[Thread-0,5,main]执行结束
          }
        };
        thread1.start();

    }

    public static void dosome(){
        Thread thread = Thread.currentThread();
        System.out.println("dosome方法线程是:"+thread);
    }
}
  • 获取线程相关信息的一组方法:
public class ThreadDemo5 {
    public static void main(String[] args) {
        Thread t1 = Thread.currentThread();
        //获取线程的名字
        String name = t1.getName();
        System.out.println(name);
        long id = t1.getId();//获取线程的唯一id
        System.out.println(id);
        int poi = t1.getPriority();//获取该线程的优先级
        System.out.println(poi);//默认是5
        //判断线程是否活着
        boolean a = t1.isAlive();
        //判断是否是守护线程
        t1.isDaemon();
        //判断线程是否被中断了
        t1.isInterrupted();
    }
}
  • void setPriority(int i);线程的优先级(不一定,只是最大程度上分配时间片):
/**
 * 线程的优先级
 * 线程有10个优先级,使用整数1-10来表示
 * 1为最小优先级
 * 10为最高优先级
 * 5为默认值
 * 线程start后会纳入到线程调度器中统一管理
 * 线程只能被动的被分配时间片并发运行,而无法
 * 主动索取时间片,线程调度器尽可能均匀的将时间片分配给每个线程
 * 调整线程的优先级可以最大程度的干涉获取时间片的几率,优先级越高的线程获取时间片的次数
 * 越多,反之则越少
 *
 */
public class ThreadDemo6 {

    public static void main(String[] args) {
        Thread max = new Thread(){
            public void run(){
                for(int i=0;i<50;i++){
                    System.out.println("max");
                }
            }
        };
        Thread min = new Thread(){
            public void run(){
                for(int i=0;i<50;i++){
                    System.out.println("min");
                }
            }
        };
        Thread norm = new Thread(){
            public void run(){
                for(int i=0;i<50;i++){
                    System.out.println("norm");
                }
            }
        };
        //设置优先级,有几率,但不准 最大程度的干涉获取时间片的几率
        norm.setPriority(Thread.MIN_PRIORITY);
        min.setPriority(Thread.NORM_PRIORITY);
        max.setPriority(Thread.MAX_PRIORITY);
        norm.start();
        min.start();
        max.start();
    }
}
  • sleep方法,睡眠
/**
 * 线程提供了一个静态方法
 * static void sleep(ling ms)
 * 使运行该方法的线程进入阻塞状态指定的毫秒,超时后线程会自动回到Runnalbe状态等待再次获取
 * 时间片并发运行
 */
public class ThreadDemo7 {
    public static void main(String[] args) {
        /**
         * 要求用户输入一个数字,然后从该数字开始每秒递减,到0时输出时间到,程序结束
         */

        while (true){
            System.out.println("请输入一个数字...");
            Scanner scanner = new Scanner(System.in);
            String str = scanner.nextLine();
            String regex = "[0-9]+";
            if(str.matches(regex)){
                int num = Integer.valueOf(str);
                for(int i=num;i>=0;i--){
                    System.out.println(i);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("计时结束...");
                break;
            }else{
                System.out.println("格式不符,请重新输入...");
            }
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值