java中多线程重要吗_JAVA多线程大总结篇

多线程

一:java语言中,实现线程的两种方式

java支持多线程机制。并且java已经将多线程实现了,我们只需要继承就行了。

第一种方式:编写一个类,直接继承java.lang.Thread,重写run方法。//定义线程类

public class MyThread extendsThread{public voidrun(){

}

}//创建线程对象

MyThread t = newMyThread();//启动线程。

t.start();

第二种方式:编写一个类,实现java.lang.Runnable接口,实现run方法。//定义一个可运行的类

public class MyRunnable implementsRunnable {public voidrun(){

}

}//创建线程对象

Thread t = new Thread(newMyRunnable());//启动线程

t.start();

注意:第二种方式实现接口比较常用,因为一个类实现了接口,它还可以去继承

其它的类,更灵活。

第三种方式: 实现Callable接口,重写call()方法,-->juc包下的 可以抛出异常,可以有返回值 (知道就行)

二:关于线程对象的生命周期

新生状态 : new的时候,线程处于新生状态

​  就绪状态 : start()线程就会进入到就绪状态,线程就会进入到就绪队列进行等 待,等待cpu的调度

​  运行状态 : cpu把资源分配给这个线程,线程才能进入运行状态

​  阻塞状态 : sleep()可以让线程进入阻塞

​  终止状态 : 线程结束

注意:

一个线程一旦进入阻塞状态,阻塞接触 无法直接恢复到运行状态,会直接进入就绪状态

如果一个线程一旦终止,无法恢复,重新创建也不是刚刚的线程

进入终止状态的情况

1. stop destroy() 不推荐使用

2. 通过标识判断–推荐

3. 线程正常执行完毕

进入就绪状态的情况

start()

阻塞解除

线程切换

yield() 礼让线程 让出CPU资源 , 原线程直接 进入就绪 状态

/*- 礼让线程 yield --> 高风亮节

- 让出cpu资源 , 原线程直接 进入就绪 状态*/

public class YieldDemo04 implementsRunnable{public static voidmain(String[] args) {

YieldDemo04 y= newYieldDemo04();new Thread(y,"A").start();new Thread(y,"B").start();

}

@Overridepublic voidrun() {

System.out.println(Thread.currentThread().getName()+"开始----------------------");

Thread.yield();

System.out.println(Thread.currentThread().getName()+"结束----------------------");

}

}

进入阻塞状态的情况

sleep()

wait()

join()

/*join() 插队线程|加入

插队之前先就绪*/

public class JoinDemo06 implementsRunnable{public static voidmain(String[] args) {

Thread th= new Thread(newJoinDemo06());for(int i = 1;i<=10;i++) {

System.out.println("main线程执行--------------"+i);if(i==5){

th.start();//就绪插队

try{

th.join(1000); //th线程插队到当前主线程中,主线程等待th线程结束,才能继续执行

} catch(InterruptedException e) {

e.printStackTrace();

}//插队

}

}

}

@Overridepublic voidrun() {

System.out.println("--------------------A线程开始执行--------------------");try{

Thread.sleep(2000);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println("--------------------A线程结束执行--------------------");

}

}

sleep(ms) : 睡眠

在sleep休眠时间过程当中,当前会让出CPU的资源, 当休眠时间解除,恢复到就绪,可供CPU选择抱着资源睡觉,—> 对象资源(对象的锁),不会释放锁

1. 网络延迟

2. 放大问题的可能性

示例:

/*根据标识做判断,控制线程的结束

龟兔赛跑

兔子每跑10步休息 , 乌龟不休息, 有人赢了就结束, 跑100步就赢了*/

public class Race02 implementsRunnable{//标识 记录赢了人的姓名

privateString winner;

@Overridepublic voidrun() {//i控制步数

for(int i =1;i<=100;i++) {//兔子 10步

System.out.println(Thread.currentThread().getName()+"正在跑第"+i+"步");if("兔子".equals(Thread.currentThread().getName()) && i%10==0) {try{

Thread.sleep(2);

}catch(InterruptedException e) {

e.printStackTrace();

}

}//判断是否要结束方法

if(!checkOver(i)) {break;

}

}

}//判断是否结束线程 返回值false结束线程 true继续跑步

public boolean checkOver(intsteps) {//是否已经有人赢了, 结束

if(winner != null) {return false;

}//没有人赢了,判断我自己赢没赢

if(steps == 100) {

winner=Thread.currentThread().getName();return false;

}return true;

}public static voidmain(String[] args) {

Race02 race= newRace02();new Thread(race,"兔子").start();new Thread(race,"乌龟").start();

}

}

三.线程的调度

1.常见的线程调度模型有哪些?

抢占式调度模型:

那个线程的优先级比较高,抢到的CPU时间片的概率就高一些/多一些。

java采用的就是抢占式调度模型。

均分式调度模型:

平均分配CPU时间片。每个线程占有的CPU时间片时间长度一样。

平均分配,一切平等。有一些编程语言,线程调度模型采用的是这种方式。

2.java中提供了哪些方法是和线程调度有关系的呢?

实例方法:void setPriority(intnewPriority) 设置线程的优先级intgetPriority() 获取线程优先级

最低优先级1

默认优先级是5

最高优先级10

优先级比较高的获取CPU时间片可能会多一些。(但也不完全是,大概率是多的。)

静态方法:

​static voidyield() 让位方法

​ 暂停当前正在执行的线程对象,并执行其他线程

​ yield()方法不是阻塞方法。让当前线程让位,让给其它线程使用。

​ yield()方法的执行会让当前线程从“运行状态”回到“就绪状态”。

​ 注意:在回到就绪之后,有可能还会再次抢到。

实例方法:

​voidjoin()

​ 合并线程

​class MyThread1 extendsThread {

​public voiddoSome(){

​ MyThread2 t= newMyThread2();

​ t.join();//当前线程进入阻塞,t线程执行,直到t线 程结束。当前线程才可以继续。

​ }

​ }

​class MyThread2 extendsThread{

}

四.关于多线程并发环境下,数据的安全问题

以后在开发中,我们的项目都是运行在服务器当中,而服务器已经将线程的定义,线程对象的创建,线程的启动等,都已经实现完了。这些代码我们都不需要编写。

​   最重要的是:你要知道,你编写的程序需要放到一个多线程的环境下运行,你更需要关注的是这些数据在多线程并发的环境下是否是安全的。

1.线程同步机制与异步机制:

异步编程模型:

线程t1和线程t2,各自执行各自的,t1不管t2,t2不管t1,

谁也不需要等谁,这种编程模型叫做:异步编程模型。

其实就是:多线程并发(效率较高。)

异步就是并发。

同步编程模型:

线程t1和线程t2,在线程t1执行的时候,必须等待t2线程执行

结束,或者说在t2线程执行的时候,必须等待t1线程执行结束,

两个线程之间发生了等待关系,这就是同步编程模型。

效率较低。线程排队执行。

同步就是排队。

2.Java中有三大变量?【重要的内容。】

实例变量:在堆中。

静态变量:在方法区。

局部变量:在栈中。

以上三大变量中:

局部变量永远都不会存在线程安全问题。

因为局部变量不共享。(一个线程一个栈。)

局部变量在栈中。所以局部变量永远都不会共享。

实例变量在堆中,堆只有1个。

静态变量在方法区中,方法区只有1个。

堆和方法区都是多线程共享的,所以可能存在线程安全问题。

局部变量+常量:不会有线程安全问题。

成员变量:可能会有线程安全问题。

如果使用局部变量的话:建议使用:StringBuilder。

因为局部变量不存在线程安全问题。选择StringBuilder。

StringBuffer效率比较低。

​   ArrayList是非线程安全的。

​   Vector是线程安全的。

​   HashMap HashSet是非线程安全的。

​   Hashtable是线程安全的。

如何控制线程安全问题:

synchronized 关键字 控制线程安全–> 控制多个线程排队执行

用法:

1.同步方法 : 简单 效率较低

​ 成员方法

​ 静态方法

2.同步块

​   synchronized(this|类.class| 资源(成员属性)){ --> this 类 资源(成员属性)要被你同步控制的代码区域–>有可能 会出现问题的代码区域}doublecheck 双重检查提高效率

注意:

同步一定要同步不变的东西,会变的锁不住,对象地址肯定不会变

同步的代码范围过大,效率低,代码范围小,锁不住

静态方法时属于 类的,同步静态方法,相当于同步类.class -->(类的class对象每一个类只有一个,不用你创建,在类加载到内存中时就已经存在)

public classSynDemo01 {public static voidmain(String[] args) {new Thread(()->{

System.out.println(SingleTon.newInstance());

}).start();new Thread(()->{

System.out.println(SingleTon.newInstance());

}).start();new Thread(()->{

System.out.println(SingleTon.newInstance());

}).start();

}

}//懒汉式

classSingleTon{//2私有的静态的该类的引用

private staticSingleTon singleTon;//1.私有的构造器

privateSingleTon(){}//A B C//3.公共的静态的访问方式,返回该类实例

public staticSingleTon newInstance() {

System.out.println("-----------------");if(singleTon == null) {

System.out.println("-----满足打印的话-----------");try{

Thread.sleep(2000);

}catch(InterruptedException e) {

e.printStackTrace();

}//双重检查 double check -->提高效率

synchronized (SingleTon.class) { //同步类

if(singleTon == null) {

singleTon= newSingleTon();

}

}

}returnsingleTon;

}

public staticSingleTon newInstance() {

System.out.println("-----------------");synchronized (SingleTon.class) { //同步类

if(singleTon == null) {

System.out.println("-----满足打印的话-----------");try{

Thread.sleep(2000);

}catch(InterruptedException e) {

e.printStackTrace();

}

singleTon= newSingleTon();

}

}returnsingleTon;

}

//同步方法

public static synchronizedSingleTon newInstance() {if(singleTon == null) {try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

singleTon= newSingleTon();

}returnsingleTon;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值