多线程

概念

线程

进程中负责程序执行的执行单元,一个进程至少有一一个线程。

多线程

解决多任务同时执行的需求 ,合理使用CPU资源。多线程的运行时根据CPU切换完成,如何切换由CPU决定,因此多线程运行具有不确定性

创建线程

继承Thread类,扩展线程

 

1

2

3

4

5

6

7

8

9

 

class DemoThread extends Thread {

@Override

public void run() {

super.run();

// Perform time-consuming operation...

}

}

DemoThread t = new DemoThread();

t.start();

  • 继承Thread类,扩展线程
  • 创建线程对象,用start()方法启动线程。

实现Runnable接口

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

 

public class Test2 {

public static void main(String[] args) {

//创建对象

MyRunnable mr = new MyRunnable();

Thread t = new Thread(mr);

//启动

t.start();

try{

for(int i = 0;i < 10;i++){

Thread.sleep(1000);

System.out.println("main:" + i);

}

}catch(Exception e){}

}

}

/**

* 使用实现Runnable接口的方式实现多线程

*/

public class MyRunnable implements Runnable {

public void run() {

try{

for(int i = 0;i < 10;i++){

Thread.sleep(1000);

System.out.println("run:" + i);

}

}catch(Exception e){}

}

}

  • 实现Runnable接口
  • 使用new Thread(Runnable实现对象),创建线程

问题

线程和进程之间的区别

一个进程时一个独立的运行环境,它可以被看作一个程序或者一个应用。线程是在进程中执行的一个任务。线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间,每个线程都拥有的栈内存来存储本地数据。

如何在Java中实现线程

1、继承Thread类,重写方法。
2、实现Runnable接口。

start()方法与Run()方法的区别

调用start()方法是启动新线程,线程之间没有确定执行顺序,而是CPU决定的;如果直接调用run方法,则是像普通方法一样顺序执行。

多线程优缺点

优点

  • 适当提高程序的执行效率(多个线程并行)
  • 适当提高资源利用率

    缺点

  • 占用一定的内存空间
  • 线程越多CPU调度开销越大
  • 程序复杂度上升

线程状态转换

多线程状态转换图多线程状态转换图

状态

1、新生状态
2、就绪状态
3、运行状态
4、阻塞状态
阻塞状态是由于正在运行的线程未结束,暂时让出了CPU
5、死亡状态
1、 run方法正常退出而自然死亡,
2、 一个未捕获的异常终止了run方法而使线程猝死。

方法

wait(),notify(),notifyAll()

wait():

导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll()唤醒,该方法只能在同步方法中调用。

notify():

随机选择一个在该对象上调用wait()方法的线程,解除其阻塞状态,该方法只能在同步方法或者同步块内部调用。

notifyAll():

解除所有那些在该对象上调用wait方法的线程的阻塞状态,同样方法只能在同步方法或者同步块内部调用。

wait()与sleep(long time)的区别

sleep():在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),该线程不丢失任何监视器的所属权,sleep() 是 Thread 类专属的静态方法,针对一个特定的线程。
wait() 方法使实体所处线程暂停执行,从而使对象进入等待状态,直到被 notify() 方法通知或者 wait() 的等待的时间到。sleep() 方法使持有的线程暂停运行,从而使线程进入休眠状态,直到用 interrupt 方法来打断他的休眠或者 sleep 的休眠的时间到。
wait() 方法进入等待状态时会释放同步锁,而 sleep() 方法不会释放同步锁。所以,当一个线程无限 sleep 时又没有任何人去 interrupt 它的时候,程序就产生大麻烦了,notify() 是用来通知线程,但在 notify() 之前线程是需要获得 lock 的。另个意思就是必须写在 synchronized(lockobj) {…} 之中。wait() 也是这个样子,一个线程需要释放某个 lock,也是在其获得 lock 情况下才能够释放,所以 wait() 也需要放在 synchronized(lockobj) {…} 之中。

volatile关键字

volatile是一个特殊的修饰符,只有成员变量才能使用,使变为可见,保证下一个读取操作会在前一个写操作后发生。

join()

将一个线程插入到另一个线程中执行。

Thread.yield()

线程放弃运行,将CPU控制权让出。
yield() 方法让出控制权后,还有可能马上被系统的调度机制选中来运行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值