JAVA 多线程(一)—— 基本概念

重要的概念

同步(synchronous)和异步(asynchronous)
并发(Concurrency)和并行(Parallelism)
临界区
阻塞(Blocking)和非阻塞(Non-Blocking)
锁(Deadlock)、饥饿(Starvation)和活锁(Livelock)
并行的级别

同步(synchronous)和异步(asynchronous):
(理解:ajax异步操作)
在这里插入图片描述

并发(Concurrency)和并行(Parallelism)
(单核cpu:只能并行,一个核多个线程来回切换)
在这里插入图片描述

临界区
临界区用来表示一种公共资源或者说是共享数据,可以被多个线程使用。但是每一次,只能有一个线程使用它,一旦临界区资源被占用,其他线程要想使用这个资源,就必须等待。

在这里插入图片描述
阻塞(Blocking)和非阻塞(Non-Blocking)
阻塞和非阻塞通常用来形容多线程间的相互影响。比如一个线程占用了临界区资源,那么其它所有需要这个资源的线程就必须在这个临界区中进行等待,等待会导致线程挂起。这种情况就是阻塞。此时,如果占用资源的线程一直不愿意释放资源,那么其它所有阻塞在这个临界区上的线程都不能工作。
–非阻塞允许多个线程同时进入临界区

死锁(Deadlock)、饥饿(Starvation)和活锁(Livelock)
死锁(Deadlock):
在这里插入图片描述
饥饿:饥饿是指某一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行。

活锁(更难被察觉):
举例:过斑马线,假如只有两个道,两个人相遇。两个人同时一面移动,又相遇了;然后又同时一面移动,又相遇……

并发级别

阻塞:
非阻塞:

  • 无障碍
  • 无锁
  • 无等待

阻塞:当一个线程进入临界区后,其他线程必须等待

无障碍(Obstruction-Free)
–无障碍是一种最弱的非阻塞调度
–自由出入临界区
–无竞争时,有限步内完成操作
–有竞争时,回滚数据

无锁(Lock-Free)
–是无障碍的
–保证有一个线程可以胜出

while (!atomicVar.compareAndSet(localVar, localVar+1)) 
{ localVar = atomicVar.get(); }

无等待(Wait-Free)
–无锁的
–要求所有的线程都必须在有限步内完成
–无饥饿的

线程

什么是线程
–线程是进程内的执行单元

新建线程

Thread t1=new Thread(); t1.start();

Thread.run()的实现 target 是Runnable接口 public void run() { if (target != null) { target.run(); } }

注意start() 和run() 的区别:
start()可以开启线程;run() 只是启动,并不能开启线程。

终止线程(不推荐)

Thread.stop() 不推荐使用。它会释放所有monitor
在这里插入图片描述
name 还没写入被终止,导致后面无法读到name的数据。

中断线程

public void Thread.interrupt() // 中断线程 
public boolean Thread.isInterrupted() // 判断是否被中断 
public static boolean Thread.interrupted() // 判断是否被中断,并清除当前中断状态
public void run(){
while(true){
if(Thread.currentThread().isInterrupted()){
System.out.println("Interruted!");
break;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("Interruted When Sleep");
//设置中断状态,抛出异常后会清除中断标记位
Thread.currentThread().interrupt();
}
Thread.yield();
}
}

挂起(suspend)和继续执行(resume)线程(不推荐)

–suspend()不会释放锁
–如果加锁发生在resume()之前 ,则死锁发生
在这里插入图片描述

等待线程结束(join)和谦让(yeild)

yeild 静态方法,主动谦让(很少用)

join 等待该线程结束(等你做完,再一起执行)

public final void join() throws InterruptedException
public final synchronized void join(long millis) throws InterruptedException
public class JoinMain { public volatile static int i=0; 
public static class AddThread extends Thread{ @Override public void run() 
{ 
	for(i=0;i<10000000;i++); 
} 
} 
	public static void main(String[] args) throws InterruptedException 
	{ 
	AddThread at=new AddThread(); 
	at.start();
	 at.join(); 
	 System.out.println(i); 
	 } 
}
##join的本质 
while (isAlive()) 
{ wait(0); }

注意:不要在Thread实例上使用 wait()和notify()方法 ,notifyall() (一般属于系统会调用,所以效果并不如你所愿)
notifyall()属于java虚拟机的操作

注意:notify()唤醒后,含有wait()的线程也不是马上执行,它要先拿到资源才能继续执行)

守护线程

在后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程就可以理解为守护线程
当一个Java应用内,只有守护线程时,Java虚拟机就会自然退出

注意:在start()前调用,告诉它是守护线程

Thread t=new DaemonT(); 
t.setDaemon(true);
 t.start();

线程同步操作

synchronized
–指定加锁对象:对给定对象加锁,进入同步代码前要获得给定对象的锁。
–直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。
–直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。

指定加锁对象

public void run() 
{ 
for(int j=0;j<10000000;j++)
 {
  synchronized(instance)
  { 
 	 i++; 
  } 
 }
}

用在方法上

public synchronized void increase()
{
 i++; 
 }

作用于静态方法

public static synchronized void increase()
{ 
	i++; 
}

Object.wait()
在这里插入图片描述
Obejct.notify(),Obejct.notifyAll()
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值