多线程

1、多线程

1、线程与进程

1、进程

是指一个内存运行中的应用程序,每个进程都有一个独立的内存空间

2、线程

是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行,一个进程至少有一个线程,

线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径又可以划分成若干个线程

2、线程调度

java:抢占式调度:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,

CPU 使用抢占式调度模式在多个线程间进行着高速的切换,对于 CPU 而言,某个时刻只能执行一个线程,而 CPU 在多个线程之间切换的速度很快,看上去就是在同一时刻运行,多线程程序并不能提高程序的运行速度,但是能够提高程序的运行效率,让 CPU 的使用率更高,

3、创建

1、Thread

新建一个类,继承 Thread ,重写 run()方法,run 方法内就是新线程要做的事,通过调用 start()方法来开启

public class Demo1 {
    public static void main(String[] args) {
        A a = new A();
        a.start();
        for (int i = 0;i < 10;i++) {
            System.out.println(i);
        }
    }
}
class A extends Thread{
    @Override
    public void run() {
        for (int i = 10;i < 20;i++) {
            System.out.println(i);
        }
    }
}

2、Runnable

实现 Runnable 接口,重写 run()方法,run 方法内就是新线程要做的事,将实现 Runnable 的对象传给 Thread 对象,再通过 Thread 对象调用 start()方法,

public class Demo1 {
    public static void main(String[] args) {
        A a = new A();
        Thread t = new Thread(a);
        //t.setDaemon(true);设置为守护线程
        t.start();
        for (int i = 0;i < 10;i++) {
            System.out.println(i);
        }
    }
}
class A implements Runnable{
    @Override
    public void run() {
        for (int i = 10;i < 20;i++) {
            System.out.println(i);
        }
    }
}

4、守护线程

用户线程:我们创建的每一个线程都是用户线程,当一个进程不包含任何的存活(运行)的用户线程时,运行结束,

守护线程:用于守护用户线程,当最后一个用户线程结束时,所有守护线程会自动结束,在调用 start()方法前,调用 setDaemon(true)方法,可将线程设置为守护线程

5、线程安全

当多个线程对数据进行操作时,可能会发生数据错乱的问题

1、同步代码块(隐式锁)

synchronize(锁对象){需要同步的代码块}

锁对象必须是同一个才能起到效果。

2、同步方法(隐式锁)

synchronize修饰方法,将需要排队执行的方法锁住,如果方法不是静态的,那么它的锁对象是this,如果是静态的,那么它的锁对象是 类名.class,当有多个方法被synchronize修饰时,有一个方法被使用,其他的方法也会被锁住

3、显示锁

Lock l = new ReentrantLock();
l.lock();//上锁
....//需要锁住的内容
l.unlock();//开锁

4、公平锁和非公平锁

公平锁:先来先用

Lock l = new ReentrantLock(true);//显示锁在创建时传入 true 为公平锁
l.lock();//上锁
....//需要锁住的内容
l.unlock();//开锁

非公平锁:谁抢到谁用(java默认)

5、线程死锁

A 调用了 B,B 调用了 A,但是因为锁住了,所以 A 在等 B 执行完,而 B 也在等 A 执行完,就这样卡住了

public class Demo2 {
    public static void main(String[] args) {
        //线程死锁
        Culprit c = new Culprit();
        Police p = new Police();
        new MyThread(c,p).start();
        c.say(p);
    }
    
    static class MyThread extends Thread{
        private Culprit c;
        private Police p;
        MyThread(Culprit c,Police p){
            this.c = c;
            this.p = p;
        }
        @Override
        public void run() {
            p.say(c);
        }
    }
    
    static class Culprit{
        public synchronized void say(Police p){
            System.out.println("罪犯:你放了我,我放了人质");
            p.fun();
        }
        public synchronized void fun(){
            System.out.println("罪犯被放了,罪犯也放了人质");
        }
    }
    
    static class Police{
        public synchronized void say(Culprit c){
            System.out.println("警察:你放了人质,我放了你");
            c.fun();
        }
        public synchronized void fun(){
            System.out.println("警察救了人质,但是罪犯跑了");
        }
    }
}

6、多线程通信

使用 Object 类中的 wait()方法休眠和 notifyAll()方法唤醒,

7、线程池

1、缓存线程池
//创建:ExecutorService service = Executors.newCachedThreadPool();
//service.execute()方法调用
2、定长线程池
//创建:ExecutorService service = Executors.newFixedThreadPool(长度);
//service.execute()方法调用
3、单线程线程池
//创建:ExecutorService service = Executors.newSingleThreadPool();
//service.execute()方法调用
4、周期性任务定长线程池
//创建ScheduleExecutorService service = Executors.newScheduleThreadPool(长度);
//分两种:1、定时执行,2、周期性执行
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值