美文网首页
线程学习笔记(一)

线程学习笔记(一)

作者: 木豚 | 来源:发表于2017-04-11 23:09 被阅读0次

    线程和进程区别

    什么是进程,程序运行的时候会对应一个进程,进程就是处于运行的程序,进程具有并发性。什么是线程,线程是轻量级进程,是进程的执行单元。

    并发性:多个进程再单个处理器上并发执行,多个进程之间不会互相影响
    并行性:在同一时刻,有多条指令在多个处理器上同时执行

    线程的三种实现方法

    public class test {
    
         public static void main(String[] args) {
             MyThread1 t1 = new MyThread1();
             Thread t2 = new Thread(new MyThread2(),"Runnable接口实现的线程");
    
             FutureTask<Integer> task = new FutureTask<>(new MyThread3());
             Thread t3 = new Thread(task,"Callable接口实现的线程");
    
             t1.start();
             t2.start();
             t3.start();
             System.out.println("Callable接口实现的线程的返回值是"+task.get());
         }
    }
    class MyThread1 extends Thread{
         //继承Thread方法实现
         @Override
         public void run() {
             this.setName("继承实现的线程");
             for (int i = 0; i < 100; i++) {
                  System.out.println(this.getName()+"的循环变量i的值为"+i);
             }
         }
    
    }
    class MyThread2 implements Runnable{
    
         @Override
         public void run() {
             for (int i = 0; i < 100; i++) {
                  System.out.println(Thread.currentThread().getName()+"的循环变量i的值为"+i);
             }
         }
    }
    class MyThread3 implements Callable<Integer>{
    
         @Override
         public Integer call()  {
             int i = 0;
             for (; i < 100; i++) {
                  System.out.println(Thread.currentThread().getName()+"的循环变量i的值为"+i);
             }
             return i;
         }
    
    }
    

    输出

    继承实现的线程的循环变量i的值为0
    Callable接口实现的线程的循环变量i的值为0
    Runnable接口实现的线程的循环变量i的值为0
    Callable接口实现的线程的循环变量i的值为1
    继承实现的线程的循环变量i的值为1
    ...
    Callable接口实现的线程的返回值是100
    
    • Callable接口是Runnable接口的增强版,Callable接口提供call()方法作为线程执行体,call()方法可以有返回值,也可以抛出异常
    • java程序运行时main()方法的方法体会执行默认的主线程

    线程的生命周期

    新建:当程序使用new关键字创建一个线程之后
    就绪:当线程对象调用start()方法之后
    运行:开始执行run()方法的线程执行体
    阻塞:当遇到会使程序停止的条件,如调用sleep()方法、调用阻塞式IO方法、线程在等待某个通知(notify)、调用suspend()方法(不推荐)
    死亡:线程正常结束、抛出异常、stop()(不推荐)死亡的线程无法再次调用start()会引发IllegalThreadStateException异常

    来自疯狂Java讲义第三版

    线程控制

    • join:当在某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()方法加入的join线程执行完为止
    public class test {
         public static void main(String[] args) throws InterruptedException {
             MyThread1 t1 = new MyThread1("新线程");
             MyThread1 t2 = new MyThread1("join线程");
             t1.start();
             for (int i = 0; i < 100; i++) {
                  if (i == 20) {
                      t2.start();
                      t2.join();
                  }
                  System.out.println(Thread.currentThread().getName()+"的循环变量i值为"+i);
             }
         }
    }
    
    class MyThread1 extends Thread{
         MyThread1 (String name) {
             super(name);
         }
         @Override
         public void run() {
             for (int i = 0; i < 100; i++) {
                  System.out.println(this.getName()+"的循环变量i的值为"+i);
             }
         }
    
    }
    

    输出

    新线程的循环变量i的值为0
    main的循环变量i值为0
    ....新线程核main交叉循环...
    新线程的循环变量i的值为29
    join线程的循环变量i的值为0
    ...当main到19停止,join和新线程交叉循环...
    join线程的循环变量i的值为98
    join线程的循环变量i的值为99
    main的循环变量i值为20
    main的循环变量i值为21
    ...当join线程结束后,main线程继续...
    
    
    • sleep:线程睡眠
    • yield:线程让步
      俩者区别:sleep()暂停后会不管其他线程优先级给其他线程执行机会,但yield()只会给相同或更高的线程机会
      sleep()后线程变为阻塞状态,yield()后线程会变成就绪状态
      yield()没有声明抛出任何异常
      sleep()yield()有更好的可移植性,通常不建议使用yield()方法控制并发线程
    • 设置线程优先级:高优先级有较多的执行机会,通过setPriority()方法设置

    相关文章

      网友评论

          本文标题:线程学习笔记(一)

          本文链接:https://www.haomeiwen.com/subject/tehpattx.html