JAVA多线程编程
并发和并行
- 并行:在同一时刻,有多个指令在多个CPU上同时执行
- 并发:在同一时刻,有多个指令在单个CPU上交替执行
进程和线程
进程:正在运行的程序
- 独立性:独立运行的单位,也是系统分配资源和调度的独立单位
- 动态性:进程动态产生,动态消亡
- 并发性:可以同其他进程一起并发执行
- 线程:进程中单个顺序控制流,是一条执行路径
多线程实现方式
- 继承Thread类的方式进行实现
- 实现Runnable接口的方式进行实现
- 利用Callable和Future接口方式实现
方式一:继承Thread类
- 定义一个继承Thread的类
package class_1_threw;
public class Mythread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100 ; i++){
System.out.println("线程开始了"+i);
}
}
}
package class_1_threw;
public class main {
public static void main(String[] args) {
Mythread t1 = new Mythread();
Mythread t2 = new Mythread();
t1.start();
t2.start();
}
}
线程开始了0
....
线程开始了22
.....
线程开始了36
....
线程开始了43
线程开始了5
线程开始了44
- 随机性
Q: 为什么要重写run方法?
A: 因为run()方法是用来封装呗线程执行的代码
Q: run() 和 start() 有什么区别
A:如果执行run则是仅仅是创建对象调用的方法并没有开启方法
start开启一条线程
由jvm调用线程的run方法
方式2 Runnable接口
- 定义类继承Runnable接口
- 在类中重写run()方法
- 创建类的实例对象
- 创建Thread类对象,把继承Runnable接口类的对象作为构造方法参数
package class_2_Runnable;
public class main {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();//创建参数对象
Thread t1 = new Thread(mr); // 创建线程
Thread t2 = new Thread(mr); // 创建线程
t1.start();
t2.start();
}
}
package class_2_Runnable;
public class MyRunnable implements Runnable{
@Override
public void run() {
// 线程启动后执行的代码
for (int i = 0; i < 100; i++) {
System.out.println("Runnable实现多线程"+i);
}
}
}
Runnable实现多线程0
Runnable实现多线程1
Runnable实现多线程0
Runnable实现多线程2
Runnable实现多线程1
Runnable实现多线程3
Runnable实现多线程2
Runnable实现多线程4
方式三:Callable和Future
- 定义一个类实现Callable接口
- 在类中实现call()方法
- 创建Callable实现类的对象
- 创建Future的实现类实现类FutureTask对象,把Callable实现类的对象作为构造方法的参数
package class_4_Called;
import java.util.concurrent.Callable;
public class Called implements Callable<String> {
@Override
public String call() throws Exception {
for (int i = 0; i < 100; i++) {
System.out.println("怪物接受攻击伤害"+i);
}
return "怪物死亡"; // 返回值就表示线程运行完之后的结果
}
}
package class_4_Called;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
public class main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Called m = new Called(); //线程
FutureTask<String> f = new FutureTask<>(m); //中介
Thread t1 = new Thread(f);
t1.start();
System.out.println(f.get());
}
}
...
....
..
怪物接受攻击伤害86
怪物接受攻击伤害87
怪物接受攻击伤害88
怪物接受攻击伤害89
怪物接受攻击伤害90
怪物接受攻击伤害91
怪物接受攻击伤害92
怪物接受攻击伤害93
怪物接受攻击伤害94
怪物接受攻击伤害95
怪物接受攻击伤害96
怪物接受攻击伤害97
怪物接受攻击伤害98
怪物接受攻击伤害99
怪物死亡
Thread一些的方法
- getName() 获取当前线程名称
package class_5_Thread_method;
public class main {
public static void main(String[] args) {
getnamess a = new getnamess();
a.start();
new getnamess().start();
new getnamess().start();
}
}
Thread-1
Thread-2
Thread-0
package class_5_Thread_method;
public class getnamess extends Thread{
@Override
public void run() {
Thread t = currentThread();
System.out.println(t);
// String a = getName();
// System.out.println(a);
}
}
- Sleep 使当前执行的线程以指定的毫秒数暂停
public class main {
public static void main(String[] args) throws InterruptedException {
// getnamess a = new getnamess();
// a.start();
// new getnamess().start();
// new getnamess().start();
for (int i = 0; i < 20; i++) {
Thread.sleep(1000);
System.out.println(i);
}
}
}
setname 设置线程名称
package class_5_Thread_method; public class main { public static void main(String[] args) { getnamess a = new getnamess(); a.setName("阿伟") a.start(); new getnamess().start(); new getnamess().start(); } }