线程

线程

要说线程,必须得先说进程,线程是依赖于进程存在的!

进程:能够调用系统资源的独立单位。
多进程的意义:为了提高CPU的使用率。比如多进程计算机,在打游戏的同时听音乐是同时进行的吗?答案不是同时的,只是感觉上是,CPU的一点点时间片在两个进程之间高效的来回切换。

线程:线程依赖于进程存在,线程是进程中某一个任务。
多线程的意义:为了让多个任务在互相抢占CPU的执行权;线程的执行具有随机性。

多线程面试题1

JVM是多线程的吗?

  • JVM是多线程的,至少有两条线程
    1)main方法:“用户线程"或者"主线程” ,JVM调用main方法
    2)垃圾回收线程,在内存中不断的通过垃圾回收器释放空间

使用Java语言如何实现多线程环境?

  • 实现多线程环境:
    创建系统资源(产生进程)----->Java语言不能系统资源—>所以Jdk提供了一个类:
    Thread类:是封装的线程类(里面一些功能的底层实现(C/C++语言)系统资源创建)Java 虚拟机允许应用程序并发地运行多个执行线程

实现方式1:—>继承关系

  • 1)自定义类 继承自Thread类(线程类)
  • 2)在当前自定义的类中:重写run方法 (执行耗时的操作)(jvm会自动的让子线程执行run方法)
  • 3)在"用户线程"main ,创建该类对象
  • 4)启动线程 (执行子线程)

多线程面试题2

  1. 新建状态
    NEW----->等价 public static final …;

  2. 线程就绪(等待执行)
    RUNNABLE

  3. 线程阻塞(线程睡眠…)
    BLOCKED

  4. 线程等待中 (线程在执行期间,利用wait()方法)(死死等待)
    WAITING

  5. 超时等待(超过一定时间,然后等待结束)

    TIMED_WAITING

  6. 线程死亡

    TERMINATED

线程的优先级

//线程的优先级: 也遵循线程的执行具有随机性!
 	//public static final int MAX_PRIORITY 10  :最大优先级 10	
 	//public static final int MIN_PRIORITY 1 	:最小优先级 1
 	//public static final int NORM_PRIORITY 5 :默认优先级 5
 		
 		/*优先级越大的线程:抢占到CPU的执行权越大
 		越小的优先级的线程:抢占到CPU的执行权越小
 		默认的优先级:抢占到CPU的执行权相等的*/
 		
 		
 		//public final int getPriority():获取优先级
 		//public final void setPriority(int newPriority):设置优先级
 				newPriority : 1:最小优先级
 							  5:默认的优先级
 							  10:最大优先级

实现方式2

方式1是继承关系,继承关系具有弊端:局限性 ,继承当前Thread类重写run方法之后将Thread类中所有的公共的功能都继承过来了,不能体系扩展功能!

* 1)自定义一个类,实现Runnable接口(里面只有一个抽象方法)函数式接口
  • 2)重写接口中的run方法,run方法中执行耗时的操作
  • 3)在主线程(main)中,创建当前自定义类的对象(资源对象)
  • 4)创建Thread类对象,将上面3)资源对象作为参数进行传递

Thread(Runnable target):创建线程类对象 不设置名称
Thread(Runnable target, String name):创建线程类对象同时设置线程名称

  • 5)启动线程 start()方法

Java中的同步机制

  • 解决线程安全问题的标准
    1)程序是否是多线程环境 ;
    2)是否有共享数据;
    3)是否存在多条语句对共享数据的操作 。

解决方案
1,2)不能改动,首先需要使用多线程程序;
针对3)来进行改动,如果能够将多条语句多共享数据的操作包裹起来,形成一个代码块—解决这个问题:

  • Java提供了专业名称:Java同步机制---->同步代码块 synchronized (同步锁(悲观锁))
//格式:		
  				synchronized(锁对象){   
  						多条语句对共享数据的操作;
	 			}
  • 注意锁对象:必须是同一个锁对象,否则不是同一把锁,还是会存在线程安全问题!
  • 锁对象:可以是任意的Java类型(包含Object以及JDK提供的类或者自定类的对象)

同步方法

什么是同步方法?
如果一个方法的方法体就是一个同步代码块的话,将synchronzied关键字放到方法声明上
形式一个同步方法(非静态)

//格式:
 			 权限修饰符  synchronized 返回值类型 方法名(形式参数){
 					....
 			}

同步方法的锁对象:是this 代表当前类对象的地址值引用!
静态的同步方法的锁对象:是当前类名.class属性(可以获取当前类的字节码文件对象 :Class)

JDK5以后提供了更具体的锁定操作,可以获取锁以及释放锁,它和synchronized用法一样,提供很多功能。
Lock 接口,不能实例化提供了,更具体的锁:可重入锁:ReentrantLock

  • public void lock():获取锁
  • public void unlock():试图释放该锁

Java中的等待唤醒机制 (使用锁对象调用wait()/notify())

生产消费者模式(管线法)

  • 生产者线程:生产者线程不断的产生数据,当没有数据,等待产生数据,通知(notify())消费者线程使用数据;
  • 消费者线程:消费者不断的使用数据,当有数据了,等待消费掉,如果没有数据了,通知(notify())生产者线程产生数据。

sleep和wait()方法的区别?

1)来源不同
sleep()来源于Thread类
wait()来源于Object类 ----->跟锁对象有关系!
2)是否会释放锁:
sleep(long time)调用不会释放锁,暂定执行,当前睡眠到了,又重新开始运行!
wait():调用时,会立即释放锁,使用notify()唤醒对方线程,解决死锁问题!
3)共同点:
这两个方法都会抛出异常:InterruptedException:中断
都属于阻塞式方法;

多线程实现方式3—>线程池

线程池:(ExceutorService)

  • 特点:
    线程池:产生一个固定的可重用的线程数,线程对象创建完毕并且执行完毕,不会被 GC回收掉,而是将该线程对象再次归还到线程池中,等待下次重复利用!
    数据库连接池(第三方的东西:阿里巴巴 druid:德鲁伊 /c3p0):产生一个固定的可用的连接池,记录最大的链接数量是多个,记录最小的链接数是多少个,一旦超出了最大连接数量,将这里面某一个连接对象colse()掉,归还到连接池中!

  • 无论线程池还是连接池弊端,使用成本要比传统的的开启子线程成本大!

ExecutorService:接口 线程池:如何实例化?
不能直接实例化,所以提供工厂类:Executors
public static ExecutorService newFixedThreadPool(int nThreads):创建固定的可重用的线程数的线程池!
ExecutorService 的API:

  • 提交异步任务:
  • Future submit(Callable task)
  • Callable:异步任务接口 :
  • 有一个抽象方法:V call() throws Exception:具体计算结果值
  • Future submit(Runnable task,T result)
  • Future:接口:表示异步任务计算的结果
  • void shutdown() :将之前提交的异步任务按照顺序关闭!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值