线程(一)

一.问题

1.程序代码一般都是顺序执行的,如何让程序在运行过长中,实现多个代码段的同时运行?
2.如何创建一个线程?创建线程的两种方式分别是什么?
3.线程为什么要休眠?
4.Thread类都有哪些方法?
5.如何实现线程内部的数据共享?

二.目标

1.学习java中线程的使用
2.掌握线程的调度和控制方法

三.Thread 类创建线程

1.通过Thread类创建线程
Thread类
·直接继承了Object类,并实现了Runnable接口。位于java.lang包中
·封装了线程对象需要的属性和方法
2.继承Thread类--创建多线程的方法之一
·从Thread类派生一个子类,并创建子类的对象
·子类应该重写Thread类的run方法,写入需要在新线程中执行的语句段。
·调用start方法来启动新线程,自动进入run方法。
在新线程中完成计算
public class FactorialThread extends Thread {
    private int num;
    public  FactorialThread(int num){
        this.num=num;
    }

    @Override
    public void run() {
        int i = num;
        int result=1;
        System.out.println("new thread started");
        while (i>0){
            result = result*i;
            i=i-1;
        }
        System.out.println("the factorial of "+num+"is "+result);
        System.out.println("new thread ends");
    }
}
 public static void main(String[] args) {
        System.out.println("main thread starts");
        FactorialThread thread = new FactorialThread(10);
        thread.start();
        System.out.println("main thread ends");

    }
3.结果说明
·main 线程已经执行完成,新线程才执行完
·main方法调用thread.start()方法启动新线程后并不等待run方法返回就继续运行,线程的run方法在一边独自运行,不影响原来的main方法的运行
4.修改:延长主线程
·如果启动新线程后希望主线程多持续一会在结束,可在start 语句后加上当前线程(这里当然是main)休眠1毫秒的语句:
 public static void main(String[] args) {
        System.out.println("main thread starts");
        FactorialThread thread = new FactorialThread(10);
        thread.start();
        try {
            Thread.sleep(1000);
        }catch (Exception e){
        }
        System.out.println("main thread ends");
}
5 创建3个新线程,每个线程睡眠(0~6秒),然后结束
public static void main(String[] args) {
      TestThread thread1 = new TestThread("thread1");
      TestThread thread2 = new TestThread("thread2");
      TestThread thread3 = new TestThread("thread3");
      System.out.println("starting threads");
      thread1.start();
      thread2.start();
      thread3.start();
      System.out.println("Threads started , main ends\n");
  }
public class TestThread extends Thread {
  private int sleepTime;

  public TestThread(String name) {
      super(name);
      sleepTime = (int)(Math.random()*6000);
  }

  @Override
  public void run() {
      try {
          System.out.println(getName()+"going to sleep for "+sleepTime);
          Thread.sleep(sleepTime);
      }catch (InterruptedException exception){

      }
      System.out.println(getName()+"finished");
  }
}
·运行结果

starting threads
Threads started , main ends

thread1going to sleep for 1809
thread2going to sleep for 1568
thread3going to sleep for 775
thread3finished
thread2finished
thread1finished

·说明
1.由于线程 休眠时间最长,所以最后结束,线程 休眠时间最短,所以最先结束
2.每次运行,都会产生不同的随机休眠时间,所以结果都不相同

Thread类--常用API方法

名称 技能
public Thread() 构建一个新的线程对象,默认名为Thread-n ,n是从0开始递增的整数
public Thread (Runnable target) 构造一个新的线程对象,以一个现实Runnable接口的类的对象为参数。默认名为Thread-n ,n是从0开始递增的整数
public Thread (String name) 构造一个新的线程对象,并同时制定线程名
public static Thread currentThread 返回当前正在运行的线程对象
public static void yieId() 使当前线程对象暂停,允许别的线程开始运行
public static void sleep(long millis) 使当前线程暂停运行制定毫秒数,但此线程并不失去已获得的锁。
public void start() 启动线程,jvm将调用此线程的run方法,结果是将同时运行两个线程,当前线程和执行run方法的线程
public void run() Thread 的子类应该重写此方法,内容应为该线程应执行的任务
public final void stop() 停止线程运行,释放该线程占用的对象锁
public void interrupt() 中断此线程
public final void join() 如果此前启动了线程A,调用join方法将等待线程A死亡才能继续执行当前线程
public final void join(long millis) 如果此前启动了线程A,调用join方法将等待指定毫秒数或者线程A死亡才能继续执行当前线程
public final void setPriority(int newPriority) 设置线程优先级
pubic final void setDaemon(Booleanon) 设置是否为后台线程,如果当前运行线程均为后台线程则jvm停止运行。这个方法必须在start()方法前使用
public final void checkAccess() 判断当前线程是否有权力修改调用此方法的线程
public void setName(String name) 更改本线程的名称为指定参数
public final boolean isAlive() 测试线程是否处于活动状态,如果线程被启动并且没有死亡则返回true

四、通过Runable接口构造线程

1.Runable接口
·只有一个run()方法
·Thread类实现了Runable接口
· 便于多个线程共享资源
· java不支持多继承,如果已经继承了某基类,便需要实现Runable接口来生成多线程
· 已实现Runable的对象为参数建立新的线程
· start 方法启动线程就会运行run()方法
2.使用Runable接口实现上面单线程的例子
    public static void main(String[] args) {
        System.out.println("mian thread starts");
        FactorialThread thread = new FactorialThread(10);
        new Thread(thread).start();
        System.out.println("new thread started ,main thread ends");
    }
3.两种线程构造方式的比较
· 使用runnable接口
①可以将CPU,代码和数据分开,形成清晰的模型;还可以从其他类继承
·直接继承Thread类
① 编写简单,直接继承,重写run方法,不能再从其他类继承
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。