Java线程概述

1、创建线程的方法?

// 第一种
Thread thread = new Thread();

// 第二种
class TestRunnable implements Runnable{}
new Thread(testRunnable).start();

//第三种
public class Test3 implements Callable<Integer> {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<>(new Test3());
        //创建线程传入FutureTask实例对象
        new Thread(futureTask).start();
        // futureTask.get()得到返回值
        Integer integer = futureTask.get();
    }
    @Override
    public Integer call() throws Exception {
        return null;
    }
}

2、Thread常用方法?

//常用构造器
Thread t1 = new Thread();
Thread t2 = new Thread("线程名称");
Thread t3 = new Thread(new Runnable() {
       @Override
       public void run() {
                
       }
}, "线程名称");

// 静态方法
currentThread():返回当前正在执行的线程;
interrupted():返回当前执行的线程是否已经被中断;
sleep(long millis):使当前执行的线程睡眠多少毫秒数;
yield():使当前执行的线程自愿暂时放弃对处理器的使用权并允许其他线程执行;

3、run()和start()区别?

run()方法是线程的执行者,表示线程需要完成的任务。start()方法是启动线程。

调用start()启动方法,会启动子线程执行run()方法。

如果直接调用run()方法,则在当前线程执行run()方法,不会启动子线程执行run(),这时run()就相当于一个普通方法。

 4、线程的生命周期

新建(new)-》就绪(start)-》运行(run)-》阻塞(sleep、await)-》死亡(stop)

new 完处于新建状态
start 完处于就绪状态, 得到CUP资源进入运行状态
sleep、阻塞式IO、等待同步锁、等待通知、suspend方法挂起 会进入阻塞状态
死亡状态:run()或call()方法执行完成,线程正常结束。线程抛出一个未捕获的Exception或Error。直接stop(方法弃用了,可能导致死锁)

 5、线程中sleep和wait的区别?

(1)sleep来自Thread类,静态方法,而wait来自Object类的普通方法。

(2)sleep会让出cpu,不会释放锁资源,而wait会释放锁资源,但是需要手动notify(),notifyAll()重新获取锁。

(3)sleep可以在任何地方使用,而wait只能在同步代码块或同步方法中使用。

(4)sleep必须指定时间,而wait可以不指定时间。

 6、volatile关键字的作用?

当一个变量被定义成volatile之后,他将具备两项特性:

1、保证可见性
在修改一个volatile变量时,JMM会把线程工作内存的变量强转刷新到主内存中,这个修改会导致其他线程中的volatile缓存无效
2、禁止指令重排
使用volatile关键字修饰共享变量,可以禁止指令重排序,比如在懒汉式单例模式中,用双重校验锁+volatile。 必须使用volatile禁止指令重排,不然new对象对于JVM最少分为三步的,①分配内存和默认变量,②赋初始值,③对象指向空间。 如果先执行了③,其他线程进入立马返回对象,返回的这个对象是有问题的。
即执行到volatile变量时,其前面的所有语句都执行完,后面所有语句都未执行。且前面语句的结果对volatile变量及其后面语句可见
虽然volatile能够保证可见性,但它能不保证原子性,volatile变量在各个线程的工作内存中是不存在一致性问题的,但是在Java里面的运算操作符并非原子操作,比如i++, 分为三步:①把 i 拷贝到线程工作内存,给 i自增, 把 i 放回主内存。如果线程A把 i 拷贝到内存的时候, 线程B也拷贝的 i 然后对 i 进行自增,刷新主内存的 i ,此时线程A 要对这个已经是旧值的 i 进行自增,然后刷入主内存。
对 volatile 域的写, happens-before 于任意线程后续对 volatile 域的读,这个规则只能保证线程A读的时候读取的是最新的数据,不能保证写的时候是还是最新的。

volatile是Java虚拟机提供的轻量级同步机制,他可见性、不保证原子性,禁止指令重排
底层通过内存屏障保障可见性和有序性,由于不能保证原子性所有可能会带来线程安全问题,可以考虑用原子类来保证操作的原子性

 7、volatile 和 synchronized 的区别

volatile 是变量修饰符, synchronized 可以修饰类、 方法、 变量。
volatile 不会造成线程的阻塞, synchronized 可能会造成线程的阻塞。
volatile 保证可见性, 不保证原子性, 禁止指令重排, synchronized 保证可见性, 原子性, 不禁止指令重排

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值