线程相关问题

1 . 线程与进程区别

​ 进程:具有一定独立的功能的程序关于某个数据集合上的一次运行活动,是操作系统进行资源分配和调度的一个独立单位

​ 线程:是进程的的一个实体,是cpu调度和分派的基本单位,是比进程更小的可以独立运行的基本单位

特点:线程的划分尺度小于进程,这使多线程程序拥有高并发性

2 . 启动线程是用run方法还是star方法

​ 启动线程用star()方法,使线程所代表的虚拟处理机处于可运行状态,它由JVM调度并执行,这不意味着线程会立即执行

​ run()方法是线程启动后要进行回调(callback)的方法

	start()方法开启线程,无需等待run方法体代码执行完毕而直接执行下面的代码.
	run()方法是线程体,包含了要执行的这个线程的内容,run()方法运行结束,此线程随即终止.
	如果直接调用run方法,程序中依然只有主线程这一个线程
3 . 编写多线程的几种实现方式
  1. 通过继承Thread类
  2. 通过实现Runable接口(推荐使用,因为Thread是一个类,java中继承是单继承,一个类只有一个父类,无法继承其他类,而接口则不一样,接口更为灵活)
  3. 通过实现callable接口
4 . 解决多线程安全的几种方式
1 . 同步代码块

在代码块声明上,加上synchronize

synchronize(锁对象){
	可能会才产生线程安全的代码
}

​ (ps: 同步代码块中锁对象可以是任意对象,但是多个线程时,要使用同一个锁对象才能保证线程安全)

2 . 同步方法

​ 在方法声明上加上synchronize

public synchronize void method(){
	可能会产生线程安全的代码
}
3 . 同步锁

​ lock接口,不过需要手动获取锁和释放锁

5 . synchronized与lock与voltatile区别
	synchronized是java的关键字,在jvm层面上,lock是一个类

​	synchronized,假如A获得线程,B线程一直等待.lock获取锁,线程可以不用一直等待

​	synchronized无法判断锁的状态, lock可以判断.而且lock是可重入,公平的.
	volatile只能使用在变量级别,synchronized可以使用在变量, 类, 方法上.
​	一个线程修改volatile修饰的共享变量,其它线程可以立即可见.synchronized修饰的变量,
	 只能在当前线程访问,其它线程阻塞.
​	volatile不会造成线程的阻塞.synchronized可能会造成线程的阻塞.
6 . sleep()和wait()的区别

​ **sleep:**sleep()方法是Thread类的方法,线程通过调用该方法,进入休眠状态主动让出CPU,从而CPU可以执行其他的线程。经过sleep指定的时间后,CPU回到这个线程上继续往下执行。

​ 如何当前线程进入了同步锁,sleep()方法并不会释放锁。即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。

	如果线程在休眠时被打断,JVM就会抛出InterruptedException异常。
	因此,必须在try-catch语句块中调用sleep方法。

wait:wait()方法可以中断线程的运行,使本线程等待,暂时让出CPU的使用权,并允许其他线程使用这个同步方法。其他线程如果在使用这个同步方法时不需要等待,那么它使用完这个方法的同时,应该用notifyAll()方法通知所有由于使用了这个同步方法而处于等待的线程结束等待,曾中断的线程就会从刚才中断处继续执行这个同步方法(并不是立马执行,而是结束等待),并遵循“先中断先继续”的原则。

​ wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果)

	wait()、notify()和notifyAll()都是Object类的final方法,被所有的类继承且不允许重写的方法。
	特别需要注意的是,不可以在非同步方法中使用上述三个方法。(从功能和使用场合也可以看出)
package thread;

public class MultiThread {
    public static void main(String[] args) throws InterruptedException {
        new Thread(new Thread1()).start();
        Thread.sleep(5000);//主动让出CPU,让CPU去执行其他的线程。在sleep指定的时间后,CPU回到这个线程上继续往下执行
        new Thread(new Thread2()).start();

    }
}
  class Thread1 implements Runnable{
      @Override
      public void run() {
          synchronized (MultiThread.class){
              System.out.println("进入线程1");
              try{
                  System.out.println("线程1正在等待");
                  Thread.sleep(5000);
//                  MultiThread.class.wait();//wait是指一个已经进入同步锁的线程内(此处指Thread1),让自己暂时让出同步锁,
                                            //以便其他在等待此锁的线程(此处指Thread2)可以得到同步锁并运行。

              }catch(Exception e){
                  System.out.println(e.getMessage());
                  e.printStackTrace();
              }
              System.out.println("线程1结束等待,继续执行");
              System.out.println("线程1执行结束");
          }
      }
  }
  class Thread2 implements Runnable{
      @Override
      public void run() {
          synchronized (MultiThread.class){
              System.out.println("进入线程2");
              System.out.println("线程2唤醒其他线程");
              MultiThread.class.notify();//Thread2调用了notify()方法,但该方法不会释放对象锁,只是告诉调用wait方法的线程可以去
                                            //参与获得锁的竞争了。但不会马上得到锁,因为锁还在别人手里,别人还没有释放。如果notify()
                                            //后面的代码还有很多,需要执行完这些代码才会释放锁。
              try {
                  Thread.sleep(5000);
              }
              catch (InterruptedException e) {
                  e.printStackTrace();
              }
              System.out.println("线程2继续执行");
              System.out.println("线程2执行结束");
          }
      }
  }
7 . 线程对的五种状态

​ 新建状态、就绪状态、运行状态、阻塞状态、死亡状态

阻塞状态

​ ①调用sleep方法进入睡眠状态

​ ②线程调用一个I/O上被阻塞的操作,

​ ③线程师徒得到一个锁,而该锁正被其他线程持有

​ ④线程等待某个触发条件

​ 所谓阻塞状态,是正在运行的线程没有结束,但是咱是让出cpu,从而让其他线程获得cpu时间,得到运行

死亡状态:

​ ①线程正常退出而死亡

​ ②一个未捕获的异常终止了run方法使得线程猝死

8 . 什么是进程死锁

​ 两个进程都在等待对方执行结束才开始执行,这就造成了进程死锁,两个进程都进入了无限的等待过程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值