目录
线程简介
任务:在java中,多任务处理就是同时执行多个任务的过程;多任务处理可以通过两种方式实现:多处理和多线程。
进程:程序由指令和数据组成,必须将指令加载到cpu,数据加载至内存。进程就是用来加载指令、管理内存、管理IO的。进程可以被视为程序的一个实例;当一个程序被运行,从磁盘加载这个程序的代码到内存,这时就开启了一个进程。
线程:一个进程之内可以分为一到多个线程。一个线程就是一个指令流,将指令流中的指令以一定的顺序交给cpu执行。在java中,线程作为最小调度单位,进程作为资源分配的最小单位,线程是CPU调度和执行的单位。在windows中进程是不活动的,只是作为线程的容器。
多线程:多个线程在执行任务。
线程实现(重点)
Thread class:继承Thread类
自定义线程类继承Thread类
重写run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程
注意开启线程不一定立即执行,由CPU调度执行
缺点:oop单继承局限性
//继承Thread类
public class TestThread1 extends Thread{
@Override
public void run() {
for (int i = 0; i<20; i++){
System.out.println("测试多线程-----------");
}
}
public static void main(String[] args) {
TestThread1 testThread1 = new TestThread1();
testThread1.start();
//main线程,主线程
for (int i = 0; i<2000; i++){
System.out.println("这是主线程运行!");
}
}
}
Runnable接口:实现Runnable接口
定义MyRunnable类实现Runnable接口
实现run()方法,编写线程执行体
创建线程对象,调用staet()方法启动线程
优点:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
//实现Runnable接口
public class TestThread2 implements Runnable{
@Override
public void run() {
for (int i = 0; i<20; i++){
System.out.println("测试多线程-----------");
}
}
public static void main(String[] args) {
//创建Runnable接口的实现类对象
TestThread2 testThread2 = new TestThread2();
//创建线程对象,通过线程对象开启线程,代理
new Thread(testThread2).start();
//main线程,主线程
for (int i = 0; i<2000; i++){
System.out.println("这是主线程运行!");
}
}
}
//并发测试案例,多个线程同时操作同一对象
//存在问题:多个线程操作同一资源的情况下,线程不安全,数据紊乱
public class TestThread3 implements Runnable{
//票数
private int num = 10;
@Override
public void run() {
while (true){
if (num<=0){
break;
}
//模拟延时
try{
Thread.sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"购入第"+ num-- + "张票");
}
}
public static void main(String[] args) {
TestThread3 testThread3 = new TestThread3();
new Thread(testThread3,"张三").start();
new Thread(testThread3,"李四").start();
new Thread(testThread3,"黄牛").start();
}
}
//模拟龟兔赛跑
public class TestThread4 implements Runnable{
//获胜者
private static String winner;
@Override
public void run() {
for(int i=0;i<=100;i++){
//模拟兔子休息
if (Thread.currentThread().getName().equals("兔子") && i%10==0){
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//判断比赛是否结束
boolean flag = gameOver(i);
if (flag){
break;
}
System.out.println(Thread.currentThread().getName() + "-->跑了" + i +"步");
}
}
//判断是否完成比赛
private boolean gameOver(int steps){
//判断是否有胜利者
if (winner!=null){//已经有胜利者
return true;
}else {
if (steps >= 100){
winner = Thread.currentThread().getName();
System.out.println("winner is " + winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
TestThread4 testThread4 = new TestThread4();
new Thread(testThread4,"兔子").start();
new Thread(testThread4,"乌龟").start();
}
}
Callable接口:实现Callable接口
实现Callable接口,需要返回值类型
重写call方法,需要抛出异常
创建目标对象
创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
提交执行:Future<Boolean> result1 = ser.submit(t1);
获取结果:boolean r1 = result1.get();
关闭服务:ser.shutdownNow();
优点:可以定义返回值,可以抛出异常
缺点:实现复杂,需要创建服务、关闭服务等
//实现Callable接口
public class TestCallable implements Callable<Boolean> {
//票数
private int num = 10;
@Override
public Boolean call() {
while (true){
if (num<=0){
break;
}
//模拟延时
try{
Thread.sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"购入第"+ num-- + "张票");
}
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
TestCallable testCallable1 = new TestCallable();
TestCallable testCallable2 = new TestCallable();
TestCallable testCallable3 = new TestCallable();
//创建执行服务:
ExecutorService ser = Executors.newFixedThreadPool(3);
//提交执行:
Future<Boolean> result1 = ser.submit(testCallable1);
Future<Boolean> result2 = ser.submit(testCallable2);
Future<Boolean> result3 = ser.submit(testCallable3);
//获取结果:
boolean r1 = result1.get();
boolean r2 = result2.get();
boolean r3 = result3.get();
System.out.println(r1);
System.out.println(r2);
System.out.println(r3);
//关闭服务:
ser.shutdownNow();
}
}
线程状态
线程同步(重点)
线程通信问题
高级主题