Java 程序设计 第八章 线程

简介: Java 程序设计 第八章 线程

第8章 线程

线程可以让一个程序同时执行多个任务,在实际程序应用地非常广泛。

8.1 理解线程

8.1.1进程的概念

了解线程前先了解一下进程,进程可以看成是程序的执行,可以把一个程序的执行过程看成是一个进程。

比如我们打开一个Word程序,就有一个Word程序进程。

8.1.2 线程的概念(此处是个人理解。)

一个进程可以有多个线程,同时执行多个任务。同样用Word举例,Word显示可以看成是一个线程,编辑可以看出是一个线程。

8.1.3 线程的生命周期

线程的生命周期有4种基本状态:

1.产生

2.中断

3.非中断(运行或可运行)

4.退出

8.2 线程类设计

8.2.1 线程API类图

Thread类是线程实现的主类,其核心过程方法由Runnable接口规范。

 

8.2.2  线程类Thread的构造方法

1.Thread(String threadName);  //创建指定名称的线程类

2.Thread();                              //线程类名称系统自动指定Thread-编号

3.Thread(Runnable target)  //target为目标对象,target需要实现Runnable接口,给出run()方法。

8.3 线程实现

线程的实现一般有两种方式:

(1)创建Thread类的子类,并重新定义run()方法,用户只要创建子类对象就能建立自己的线程。

(2)创建实现Runnable接口的类,并实现run()方法。

8.3.1 继承实现

方式一:继承Thread类

public class ThreadDemo extends Thread{
  public void run() {
    //线程代码实现
    System.out.println("线程执行");
  }
  public static void main(String[] args) {
    ThreadDemo th = new ThreadDemo();
    th.start();
  }
}

8.3.2接口实现

方式二:实现Runnable接口

 

public class ThreadDemo2{
  public static void main(String[] args) {
    Thread th  = new Thread(new MyThImpl());
    th.start();
  }
}
class MyThImpl implements Runnable{
  public void run() {
    //线程代码实现
    System.out.println("线程执行");
  }
}

8.4 线程控制

8.4.1 监控线程状态

线程状态在枚举类型Thread.State中定义。

NEW:新创建,还没调用start()

RUNNABLE:run()中代码被执行

BLOCKED:阻塞,等待解锁

WAITING:另一个线程运行,本线程等待

TIMED_WAIYING:等待到指定时间

TERMINATED:线程退出run()

获取线程状态方法:

public Thread.State getState()

 

8.4.2 线程休眠

Thread的sleep()方法

public class sleep1 {
  public static void main(String[] args) throws InterruptedException {
    for(int i=0;i<20;i++) {
      System.out.println("main"+i);
      Thread.sleep(1000);
    }
  }
}

注意:(1)sleep是静态方法,睡眠的是当前运行的线程、

 

8.4.3 中断线程

public void interrupt() :中断当前阻塞与等待状态,强制线程抛出异常。

 

8.4.4 阻塞进程 join()

void join(): 当前线程等待加入该线程后面,等待该线程终止

void join(long millis):当前线程等待该线程终止的时间最长为millis毫秒,如果超时还没执行完,当前线程也会进入就绪状态。

void join(long millis, int nanos);等待时间millis毫秒+nanos纳秒

8.4.5线程等待和唤醒

public final void wait() throws InterruptedException
public final void wait(long timeout,int nanos)throws InterruptedException
void notify()
void notifyAll()

如果线程等待用sleep(),唤醒用interrupt()

等待用join(),唤醒用interrupt()

等待用wait(),唤醒用notify();

 

8.4.6线程终止

当前线程放弃调度执行权力,等待下次排队执行。

public static void yield()

 

..线程控制综合实例

 

import java.util.Scanner;
public class sleep1 {
  private static int data = -1;
  private static Thread thread = new Thread(new Runnable() {
    public void run() {
      System.out.println("线程已经启动,输入0开始计数");
      for(int i=10;i>0;i--) {
        while(data != 0) {
          Thread.yield();
        }
        System.out.println(Thread.currentThread().getName()+":"+i);
        try {
          Thread.sleep(100);
        }catch(InterruptedException e) {
          e.printStackTrace();
        }
        
      }
    }
  });
  public static void main(String[] args) {
    thread.start();
    Scanner in = new Scanner(System.in);
    while(data == -1) {
      try {
        data=Integer.parseInt(in.nextLine());
        if(data!=0) {
          System.out.println("enter 0 to start counting");
          data = -1;
        }
      }catch(NumberFormatException e) {
        System.out.println("请输入整数");
      }
    }
  in.close(); 
  }
}
 
 
 

8.5 线程属性

8.5.1 优先级

优先级较高的线程获取CPU资源的概率较大。

每个线程默认的优先级和父线程相同。

Thread类提供setPriority(int newPriority和getPriority)和getPriority()方法来设置和得到优先级。

setPriority的参数时一个整数,范围1~10. (10最高)。

优先级实例:

 
public class priority1 {
  public static void main(String[] args) {
    new MyThread("低级",1).start();
    new MyThread("高级",10).start();
  }
}
class MyThread extends Thread{
  public MyThread(String name,int pro) {
    super(name);
    setPriority(pro);
  }
  public void run() {
    for(int i=0;i<=100;i++) {
      System.out.println(this.getName()+"线程第"+i+"次执行");
    }
  }
}

多次运行可以发现,多数情况下优先级高的先运行完成。

8.5.2 守护线程

Java中有两类线程:用户线程User Thread 和 守护线程Daemon Thread

守护线程具有最低优先级,为系统其它对象提供服务。

一般不会自己操作守护进程。

 

8.6线程同步

8.6.1Synchronized同步方法和同步代码块

保护某段代码只能同时被一个线程执行的技术成为线程同步。

关键字synchronized是Java内部实现的一个简单锁,可以用synchronized锁定一段代码:

public static void biz() {
    synchronized(Object.class) {
      a++;
      b++;
      if(a!=b) {
        System.out.println(a+"!="+b);
      }
    }
  }

或者锁定整个方法:

  synchronized public static void biz() {
      a++;
      b++;
      if(a!=b) {
        System.out.println(a+"!="+b);
      }
    
  }

8.6.2 同步变量volatile关键字

Java变量前可以加修饰语volatile,volatile的主要目的是解决成员变量的多线程访问同步问题。

在读取加了volatie修饰的变量时,会直接从内存读取。

但volatile不保证对变量的操作是原子操作。

Java提供java.util.concurrent.automic包,提供了基本类型与引用类型的原子性操作封装类:

AtomicBoolean

AtomicInteger

AtomicIntegerArray

...

 

8.6.3线程锁Lock接口及ReentrantLock类

8.6.4 死锁

不同线程都在等待那些不可能被释放的锁时,就成了死锁。

构成死锁的典型是锁交叉。


相关文章
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
118 1
|
1月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
132 1
|
2月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
123 0
|
2月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
193 16
|
3月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
3月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
4月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
345 83
|
4月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
185 0
|
4月前
|
存储 Java 调度
Java虚拟线程:轻量级并发的革命性突破
Java虚拟线程:轻量级并发的革命性突破
322 83