Java 多线程概念

概念

1.一个对象就是一个线程,多个对象就是多线程,一块资源就是进程,多块资源就是多进程,多个对象抢一块资源就是并发,多个对象抢多块资源就是并行
2.一块资源就是一个或多个共享变量,多个对象共享一块资源就必须要同步锁,否则会变成多个对象每一个对象都有一块资源
3.javaw
4.主线程的入口是main,子线程的入口是run,主线程是特殊的线程,与其他子线程同时进行,不需要和其他子线程抢夺CPU资源,除非遇到线程控制方法。
start开启一条子线程,不影响当前线程运行。
join开启一条子线程后,将这条子线程加入当前线程,必须先执行完这条子线程,当前线程才能继续执行
yeild出让资源给同优先级的子线程,不影响主线程
5.开启的子线程默认是前台线程(不会因为当前线程退出而退出),setDaemon设置为后台线程(当前线程退出,后台线程必须退出),设置后台线程必须在start之前
6.线程的生命周期:
新建:new
就绪:start();一个线程只能开启一次,准备抢资源
运行:抢到资源,开始执行代码块(可能刚执行完一条代码,又被别的线程抢回去了)
阻塞:线程暂停(sleep、wait、join、suspend、IO阻塞…)
死亡:run方法执行完毕,线程退出

线程创建的三种方法

//1.新建一个类继承Thread,重写run方法,创建该类的对象,调用start方法
public class Test{
    public static void main(String[] args){
        Person per1 = new Person();
        Person per2 = new Person();
        per1.start();
        per2.start();
    }
}
class Person extends Thread{
    public void run()
    }
}
//简写形式
new Thread() {
    public void run() {
        System.out.println("我是子线程");
    }
}.start();
//2.新建一个类实现runnable接口,重写run方法,创建runnable对象,使用runnable对象来创建Thread,调用start方法
public class Test {
    public static void main(String[] args) {
        Person per = new Person();
        Thread th1 = new Thread(per);
        Thread th2 = new Thread(per);
        th1.start();
        th2.start();
    }
}
class Person implements Runnable{
    public void run() {
    }
}
//简写形式
new Thread(new Runnable() { 
    public void run() {
        System.out.println("我是子线程");
    }
}).start();
//3.新建一个类实现Callback接口,创建callback实例,用callback对象来创建futuretask实例,用futuretask对象来创建thread实例,调用thread.start方法,如果需要获取结果,可以用futuretask对象调用get方法获取线程返回,但会阻塞当前线程

同步锁

1.把访问到的共享变量全部括起来
2.括起来之后要使用同一把锁(obj、this、类类型)

线程通信(wait、notify方法)

1.必须放在同步锁中
2.调用者必须是锁
3.调用wait进入休眠状态,并释放锁

线程池概念

线程池就是管理线程,是线程的集合,线程池中的线程能够并发执行,提供了两个主要主要方法:

1.execute();开始执行任务
2.shutdown();线程池关闭,线程消失不维护
3.shutdownnow();立即关闭线程池,sleep无法终结

线程池创建

//1.缓冲线程池;第一次可以开启任意个线程,第二次开启如果有空闲的线程,就会去重用它
ExecutorService ctp = Executors.newCachedThreadPool();
ctp.execute(new Runnable() {
    @Override
    public void run() {
    }
});
//2.固定线程:不管开启多少个任务,线程池只会用3条线程来执行,执行完后复用原来3条线程
ExecutorService ftp = Executors.newFixedThreadPool(3);
ftp.execute(new Runnable() {
    @Override
    public void run() {
    }
});
//3.单线程:只开启一条线程,相当于固定线程的参数1
ExecutorService ste = Executors.newSingleThreadExecutor();
ste.execute(new Runnable() {
    @Override
    public void run() {
    }
});
//4.定时器:
ScheduledExecutorService stp =Executors.newScheduledThreadPool(1);
System.out.println("延迟任务5秒后开启");
stp.schedule(new Runnable() {
    @Override
    // 延迟任务
    public void run() {
        System.out.println("任务开启");
    }
}, 5000, TimeUnit.MILLISECONDS);
//关闭定时器
stp.shutdown();
ScheduledExecutorService stp1 = Executors.newScheduledThreadPool(1);
stp1.scheduleAtFixedRate(new Runnable() {
    int i = 5;
    @Override
    // 周期任务定时器
    public void run() {
        if (i == 0) {
            System.out.println("没了");
            stp1.shutdown();
        } else {
            System.out.println("离世界末日还有" + (i--) + "秒");
        }
    }
//6s后开启任务,每隔1s执行一次任务,ms单位
}, 6000, 1000, TimeUnit.MILLISECONDS);
//5.Timer类也有定时器功能
Timer timer = new Timer();
timer.schedule(new TimerTask() {
    int i = 5;
    @Override
    public void run() {
        System.out.println("1s执行1次," + i + "s后关闭定时器");
        if ((--i) == 0) {
            System.out.println("关闭定时器");
            timer.cancel();
        }
    }
}, 3000, 1000);
//定时器必须是单个线程

小练习

1.龟兔赛跑
2.生产者消费者(几条线程、共享变量)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值