多线程: 多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作 “多线程处理(Multithreading)”。
1. Thead类 Java 中的 JVM 允许程序运行多个线程,它通过 java.lang.Thread 类来实现。
1.1. Thread类的特性
每个线程都是通过某个特定的 Thread 对象的 run() 方法来完成操作的。
经常把 run() 方法的主体称为线程体。
通过该 Thread 对象的 start() 方法来调用这个线程。
1.2. Thread类的构造方法 1 2 3 4 Thread(); Thread(String threadname); Thread(Runnable target); Thread(Runnable target, String name);
1.3. Thread类的有关方法
Methods
Functions
public void start()
启动线程
public void run()
线程被调度后执行的操作
public final String getName()
返回线程的名称
void setName(String name)
设置线程的名称
public static Thread currentThread()
返回当前的线程
public final int getPriority()
返回当前线程的优先级
public final void setPriority(int newPriority)
设置新的线程优先级
public static void yield()
进程让步
public static void sleep(long millis) throws InterruptedException
占着 CPU,休眠
public final void stop()
强制终止线程
public final boolean isAlive()
判断线程是否还活着
public final void join() throws InterruptedException
当某个程序执行流中调用其他线程的 join() 方法时,阻塞当前线程,直到被 join 线程执行完毕。
注:线程的优先级控制(线程创建时继承父类线程的优先级)。
MAX_PRIORITY (10);
MIN_PRIORITY (1);
NORM_PRIORITY (5); 默认值
2. 创建线程的两种方式 2.1.继承 Thread 类
定义子类继承 Thread 类;
子类中重写 Thread 类中的 run() 方法;
创建 Thread 子类对象,即创建了线程对象;
调用线程对象的 start() 方法:启动线程,调用 run() 方法。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 package TestThread;public class Thread1 extends Thread { @Override public void run () { System.out.println("Thread1's code." ); for (int i = 0 ; i < 5 ; ++i) System.out.println("this is Thread1's code " + i); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 package TestThread;public class ThreadMain { public static void main (String[] args) { Thread t1 = new Thread1 (); t1.start(); System.out.println("-------1-------" ); System.out.println("-------2-------" ); System.out.println("-------3-------" ); } }
1 2 3 4 5 6 7 8 9 10 // 输出 线程之间并发 -------1------- Thread1's code. -------2------- -------3------- this is Thread1's code 0 this is Thread1's code 1 this is Thread1's code 2 this is Thread1's code 3 this is Thread1's code 4
2.2. 实现 Runnable 接口(常用)
定义子类,实现 Runnable 接口;
子类中重写 Runnable 接口中的 run() 方法;
通过 Thread 类的含参构造器创建线程对象;
将 Runnable 接口的子类对象作为实际参数传递给 Thread 类的构造方法中;
调用 Thread 类的 start() 方法:开启线程,调用 Runnable 子类接口的 run() 方法。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 package TestThread;public class Thread2 implements Runnable { @Override public void run () { System.out.println(Thread.currentThread().getName() + " " + "Thread2's code." ); for (int i = 0 ; i < 5 ; ++i) System.out.println(Thread.currentThread().getName() + " " + "this is Thread2's code " + i); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package TestThread;public class ThreadMain { public static void main (String[] args) { Thread t2 = new Thread (new Thread2 ()); Thread t3 = new Thread (new Thread2 (), "Thread-3" ); t2.start(); t3.start(); System.out.println("-------1-------" ); System.out.println("-------2-------" ); System.out.println("-------3-------" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 输出 -------1------- -------2------- -------3------- Thread-0 Thread2's code. Thread-3 Thread2's code. Thread-3 this is Thread2's code 0 Thread-3 this is Thread2's code 1 Thread-3 this is Thread2's code 2 Thread-3 this is Thread2's code 3 Thread-0 this is Thread2's code 0 Thread-3 this is Thread2's code 4 Thread-0 this is Thread2's code 1 Thread-0 this is Thread2's code 2 Thread-0 this is Thread2's code 3 Thread-0 this is Thread2's code 4
3. 多线程资源共享 使用实现接口的方法,可以避免单继承的局限性,多个线程也可以共享资源。
共享资源代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 package TestThread;public class Thread2 implements Runnable { int count = 0 ; @Override public void run () { System.out.println(Thread.currentThread().getName() + " " + "Thread2's code." ); for (int i = 0 ; i < 5 ; ++i, ++count) System.out.println(Thread.currentThread().getName() + " " + "this is Thread1's code " + count); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 package TestThread;public class ThreadMain { public static void main (String[] args) { Runnable r = new Thread2 (); Thread t1 = new Thread (r, "Thread-1" ); Thread t2 = new Thread (r, "Thread-2" ); t1.start(); t2.start(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 // 输出 Thread-1 Thread2's code. Thread-2 Thread2's code. Thread-2 this is Thread1's code 0 Thread-2 this is Thread1's code 1 Thread-2 this is Thread1's code 2 Thread-2 this is Thread1's code 3 Thread-2 this is Thread1's code 4 Thread-1 this is Thread1's code 0 Thread-1 this is Thread1's code 6 Thread-1 this is Thread1's code 7 Thread-1 this is Thread1's code 8 Thread-1 this is Thread1's code 9
4. 多线程程序的优点
提高应用程序的响应速度。对图形界面更有意义,提高用户体验;
提高 CPU 利用率;
改成程序结构。将既长又复杂的进程分为多个线程,提高可读性,便于维护。
5. 线程的声明周期 JDK 中用 Thread.State 枚举表示了线程的几种状态
线程的一个完整声明周期中通常要经历五种状态:新建、就绪、运行、阻塞、思维。
6. 线程的同步问题 参照 OS 中的进程同步、死锁。
Java 中提供了用于解决多线程同步的机制 synchronized
同步锁。
1 2 3 4 5 6 7 8 public synchronized void show (String name) { ... }synchronized (object obj) {
7. 线程通信
Methods
Functions
wait()
挂起
notify()
唤醒同步资源的等待队列指中优先最高的线程
notifyAll()
唤醒同步资源的等待队列中的全部线程
java.lang.Object 提供的这三个方法只有在 synchronized 方法或 synchronized 代码块中才能使用,否则会报 java.lang.IllegalMonitorStateException 异常