一、什么多线程
-
多线程与多进程:
线程:cpu调度的最小单位,一系列线程共享当前的资源。
进程:资源分配的最小单位,一个进程可有1-n个线程。
-
举例说明
多线程:类似高速路,里面单个车道为一个线程,多个车道可以使更多的车辆行驶,到达目的地。
多进程:类似多条高速路,其中单条高速为单进程,多条高速路可以到达不同目的地,也可到达同个目的地。
- 优缺点:
优:资源利用高,效率高。
缺:数据层面和硬件层面容易出错。对程序的运行要有全局性的考量,对程序员自身技术有要求。
- Java中开启线程的常用方式:
1)继承Thread,重写run方法,在方法体内定义线程体,无返回值。
2)实现Runnable接口,重写run方法,无返回值。《推荐写法》
3)实现juc包下的Callable接口,重写call()方法。可以有返回值。
二、开启多线程
-
通过继承Thread(不推荐,毕竟java只能单继承)
public class Multithreading01 {
//入口
public static void main(String[] args) throws Exception {
Mu01 mu01 = new Mu01();
//start()使run()线程体就绪,具体何时被执行取决于计算机(这段时间极其短,可能千分之一秒都用不上)。
mu01.start();
//这是main主线程
for (int i = 1; i <= 5; i++) {
System.out.println("我是main中方法" + i);
}
}
}
//继承Thread并重写run()
class Mu01 extends Thread {
@Override
public void run() {
for (int i = 0; i <= 5; i++) {
System.out.println("我是run方法" + i);
}
}
}
结果:
我是main中方法1
我是run方法1
我是run方法2
我是main中方法2
我是main中方法3
我是main中方法4
我是run方法3
我是main中方法5
我是run方法4
我是run方法5
-
实现Runnable接口**(推荐,毕竟能继承父类继承还能实现多接口)**
public class Multithreading02 {
public static void main(String[] args) {
// 开启多线程买票
Mul01 mul = new Mul01();
//开启多条进程
Thread th1 = new Thread(mul, "湖南老乡一");//给每个线程定一个名字,提高辨识度。
Thread th2 = new Thread(mul, "湖南老乡二");
Thread th3 = new Thread(mul, "湖南老乡三");
//多条进程进入就绪
th1.start();
th2.start();
th3.start();
}
}
//实现Runnable接口
class Mul01 implements Runnable {
private int ticket = 10;// 车票10张
@Override
public void run() {
while (true) {
if (ticket <= 0) {
break;
} else {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
//开启线程同步块。双重检查 double check -->提高效率
synchronized (this) {
if (ticket <= 0) {
break;
}
//获取到当前线程的名字并让车票减去1。Thread.currentThread().getName()为获取线程名
System.out.println(Thread.currentThread().getName() + ":购买了第 " + ticket-- + " 张票");
}
}
}
}
}
结果:
湖南老乡二:购买了第 10 张票
湖南老乡三:购买了第 9 张票
湖南老乡一:购买了第 8 张票
湖南老乡三:购买了第 7 张票
湖南老乡一:购买了第 6 张票
湖南老乡二:购买了第 5 张票
湖南老乡三:购买了第 4 张票
湖南老乡一:购买了第 3 张票
湖南老乡二:购买了第 2 张票
湖南老乡三:购买了第 1 张票
- 实现Callable接口。待续更……