1. 多线程实现最核心的机制
一个程序在其执行过程中, 可以产生多个线程, 形成多条执行线索。,每条线程,有产生、存在和消亡的过程,并且独立完成各自的功能,互不干扰。
多线程程序运行只占用一个CPU,使用“时间片轮转法”运行程序,如图:
2. Java中的多线程实现
Java应用程序总是从主类的main()方法开始执行,如果main()方法中创建了其它线程,在主线程和其它线程之间轮流切换执行,保证每个线程都有机会使用CPU,直到程序中所有线程都结束, Java应用程序才结束。
在Java中,每个线程的状态有以下四种:
线程状态切换时调用的方法在图中已标示出来,这些对线程进行操作的方法都在java.lang.Thread
类中,这个类是专门用来创建线程和对线程进行操作的类,还包括特殊的 run( )方法。
在Java中,创建线程有两种方法:
- 继承Thread类
- 实现Runnable接口
线程创建方法1—继承Thread类
具体定义方法如下:
- ① 定义类的时候继承Thread类;
- ② 重写 Thread 类的 run() 方法;
- ③ 准备在线程中完成的工作放在run() 方法实现;
定义之后创建对象,然后通过该对象调用start()方法即可启动线程。
示例代码如下:
import java.lang.Thread;
class MyThread extends Thread {
String name;
int count;
MyThread(String name, int count){
this.name = name;
this.count = count;
}
public void run() {
for(int i = 0; i < count;i++) {
System.out.println(name + ":" + i);
}
}
}
public class ThreadTest {
public static void main(String[] args) {
//创建线程
MyThread myThread1 = new MyThread("A",5);
MyThread myThread2 = new MyThread("B",5);
//启动线程
myThread1.run();
myThread2.run();
}
}
运行效果如下:
线程创建方法2—实现Runnable接口
具体定义方法如下:
- ① 定义类的时候实现Runnable接口;
- ② 重写接口中的 run() 方法;
- ③ 准备在线程中完成的工作放在run() 方法实现;
定义之后创建对象,然后通过该对象调用start()方法即可启动线程。
示例代码如下:
import java.lang.Thread;
class MyTestThread implements Runnable{
String name;
int count;
MyTestThread(String name, int count){
this.name = name;
this.count = count;
}
public void run() {
for(int i = 0; i < count;i++) {
System.out.println(name + ":" + i);
}
}
}
public class ThreadTest2 {
public static void main(String[] args) {
//创建线程
MyTestThread myThread1 = new MyTestThread("A",3);
MyTestThread myThread2 = new MyTestThread("B",3);
//启动线程
myThread1.run();
myThread2.run();
}
}
运行效果如下:
3. 多线程之间的同步和互斥
在多线程程序中,可能会有两个甚至更多的线程试图同时访问一个有限的资源,在编写程序时必须对这种潜在资源冲突进行预防。
为了解决这种冲突,在线程使用一个资源时为其加锁即可,访问资源的第一个线程为其加上锁以后,其他线程便不能再使用那个资源,除非被解锁。
加锁的方法非常简单,只需要对于访问某个关键共享资源的所有方法,加上synchronized
修饰符即可,比如:
synchronized void f();
加锁之后,其它线程想使用这个方法时就必须等待,直到线程A 使用完该方法,除非线程A主动让出CPU资源。
示例代码如下:
import java.lang.Thread;
class MySyncThread implements Runnable{
String name;
int count;
/* 所有该类对象共享资源 */
private static int number = 100;
MySyncThread(String name, int count){
this.name = name;
this.count = count;
}
public void run() {
int temp;
for(int i = 0; i < count;i++) {
temp = sub();
System.out.println(name + ":number = " + number);
//主动挂起,让出CPU
try {
Thread.sleep(2000);
}
catch (Exception e) {
System.out.println("发生异常啦!");
}
}
}
/* 上锁 */
public synchronized int sub() {
number--;
return number;
}
}
public class ThreadTest3 {
public static void main(String[] args) {
//创建线程
MySyncThread myThread1 = new MySyncThread("A",3);
MySyncThread myThread2 = new MySyncThread("B",3);
//启动线程
myThread1.run();
myThread2.run();
}
}
运行效果如下: