线程常用方法

文章详细介绍了Java中多线程的几个关键概念:join用于线程同步,保证顺序执行;sleep使线程进入阻塞状态,定时后恢复;yield让当前线程回到就绪状态,可能立即重新获取执行权。同时,对比了sleep和yield的区别。接着讨论了synchronized的锁机制,包括类锁、对象锁以及其可重入性。最后提到了volatile确保线程间变量的可见性,但无法解决同步问题。
摘要由CSDN通过智能技术生成

join方法:将一个线程添加到另一个线程中,如将t1线程添加到t2线程中,然后启动t1、t2线程(t1在前t2在后),此时t1线程执行完后再执行t2线程,如果t2中join了多个线程,这几个线程交替执行完成后再执行t2,如果t2在前则join失效,两个线程交替执行

 public static void main(String[] args) {
        testJoin();
        System.out.println("join test");
    }

    static void testJoin() {
        Thread t1 = new Thread(()->{
            for(int i=0; i<5; i++) {
                System.out.println("A" + i);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(()->{
            try {
                t1.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            for(int i=0; i<5; i++) {
                System.out.println("B" + i);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
        System.out.println("--------------------");
        t2.start();
    }

sleep: sleep方法进入阻塞状态,特定时间后进入就绪状态
static void testSleep() {
    new Thread(()->{
        for(int i=0; i<5; i++) {
            System.out.println("A" + i);
            try {
                Thread.sleep(50);
                //TimeUnit.Milliseconds.sleep(500)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();
}
yield: yield方法让出CPU进入就绪状态,可能让出后马上给你就能接着执行
static void testYield() {
    new Thread(()->{
        for(int i=0; i<50; i++) {
            System.out.println("A" + i);
            if(i%10 == 0) Thread.yield();
        }
    }).start();

    new Thread(()->{
        for(int i=0; i<50; i++) {
            System.out.println("--B" + i);
            if(i%10 == 0) Thread.yield();
        }
    }).start();
}

sleep和yield的区别:

sleep() 方法给其他线程运行机会时不考虑线程的优先级,yield() 方法只会给相同优先级或更高优先级的线程运行的机会;

线程执行 sleep() 方法后进入阻塞状态,特定时间后进入就绪状态,线程执行 yield() 方法转入就绪状态,可能马上又执行; 

sleep() 方法声明抛出 InterruptedException,yield() 方法没有声明抛出异常;

 sleep() 方法需要指定时间参数,yield() 方法出让 CPU 的执行权时间由 JVM 控制;

volatile和synchnorized:

 synchronized 给方法和代码块添加锁:

     判断synchronized是否同步访问要看加锁的对象是不是一样的,加锁的对象:

          类锁:static修饰的synchronized方法,所对象是xxxx.class 

          类对象锁:synchronized方法(synchronized的默认参数是类的实例),锁对象是类的                                         实例,和类锁不是一回事

          对象锁:方法内部的synchronized(对象)方法块,对某个属性加锁

        (1)、一个对象同时调用synchronized 方法和非synchronized方法,是可以同时运行的 

        (2)、一个对象调用两个 synchronized修饰的方法只能同步执行,因为方法是共用的类对象锁,如果一个方法出现异常释放锁,要通过try、catch防止另一个同步方法接着执行;如果是不同对象调用synchronized方法,这两个对象的执行互不影响;
       (3)、synchronized 是可重入锁:一个线程中一个同步方法可以调用另一个同步方法,一个线程已经拥有了某个对象的锁,再次申请的时候仍然会得到该对象的锁       

      (4)、synchronized(Object):参数不要使用 常量String、Integer、Long 这样的基础数据                                   常量String 是指向内存中唯一的对象,被锁住后可能会影响其他的线程
                         Integer和Long 值可能会被修改

volatile:volatile 修饰的变量在线程之间可见(变量内部的属性修改是不可见的)、禁止指令重排序

                volatile不能实现synchnorized的功能,比如两个线程同时读取A为1,此时同时修改为2,尽管线程间可见还是会有同步问题

synchronized的实践参考:记录一 :对象锁和类锁_yunfei_run的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值