Thread类的常用方法_sleep和创建多线程程序的第二种方式_实现Runnable接口

sleep方法是在Thread类中的一个静态方法,当一个线程调用了sleep方法,被调用的那个线程就会暂时的让出指定时间的CPU执行权,在这段时间也不会参与CPU的调度,当时间到了之后,就会重新回到就绪状态,等待CPU的再次调度,注意是就绪状态,而不是重新拿回CPU的执行权。并且,在休眠期间,只是会让出CPU的执行权,但是之前获得的锁资源,还是继续持有,等CPU调度到该线程重新获取到执行权的时候,就会继续运行sleep之后的代码。接下来用一个例子来说明Sleep期间不会放弃锁资源

复制代码
public class SleepDemo {
    public static void main(String[] args) throws InterruptedException {
        Lock lock = new ReentrantLock();
        Thread one = new Thread(() -> {
            lock.lock();
            System.out.println("线程A准备被Sleep"); //1
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程A被唤醒"); //2
            lock.unlock();
        });
        Thread two = new Thread(() -> {
            lock.lock();
            System.out.println("线程B准备被Sleep"); //3
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程B被唤醒"); //4
            lock.unlock();
        });
        one.start();
        two.start();
    }
}
复制代码

在上面的代码中,new了两个线程,但是只有一个锁资源lock,如果sleep期间会释放锁资源的话,那么输出结果应当是交替输出的,因为在执行代码1的时候,会被剥夺执行权,那么线程2将会拿到锁,但是事实真的是这样吗,看输出结果

线程A准备被Sleep

线程A被唤醒

线程B准备被Sleep

线程B被唤醒

可以看到,线程A被sleep的时候,线程2执行,想要获取锁I资源lock,但是发现lock被占有了,只好阻塞,然后线程1的休眠时间到了,重新获取执行权,继续执行sleep之后的代码,然后释放锁,然后线程2拿到锁,执行后续代码。通过上面的代码就可以看出,sleep期间是不会释放锁资源的,只是暂时的让出了cpu的执行权

 

 

创建多线程程序的第二种方式-实现Runnable接口

java.lang. Runnable也是非吊军儿的一种,我们只需要重与run万法即可。

步骤如下∶

  1.定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。

  ⒉创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。

  3.调用线程对象的start()方法来启动线程

复制代码
public class Demo_Runnable implements Runnable{
    @Override
    public void run() {
        for(int i = 0; i < 20; i++){
            System.out.println(Thread.currentThread().getName()+"--》"+i);
        }
    }
    public static void main(String[] args) {
        Demo_Runnable demo_runnable = new Demo_Runnable();
        Thread thread = new Thread(demo_runnable);

        thread.start();

        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+"-->"+i);

        }

    }
}
复制代码
复制代码
// 创建线程2: 实现Runnable接口,重写run()方法,执行线程需要丢入的runnable接口实现类,调用start()方法。
public class TestThread3 implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            // run方法线程体
            System.out.println("我在看代码-----" + i);
        }
    }

    public static void main(String[] args) {
        // 创建Runnable接口的实现类对象
        TestThread3 testThread3 = new TestThread3();
        // 创建线程,对象通过线程对象开启线程
//        Thread thread = new Thread(testThread3);
//        thread.start();

        new Thread(testThread3).start();
        
        for (int i = 0; i < 1000; i++) {
            System.out.println("我在学习多线程-----" + i);
        }
    }
}
复制代码

 

posted @   夫君  阅读(187)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示