并发编程相关概念知识(Java)
同步:同步方法调用开始后,调用者只有等到方法调用返回后,才能继续后续的行为。
异步:异步方法调用开始后,调用就立即返回,调用者可以继续后续的操作,方法调用执行完成时,会通知调用者。
并发:偏重于多个任务交替执行。
并行:多个任务真正的同时执行。
临界区:表示一种公共资源或者共享的资源,但是同一时间能被一个线程所占用。
阻塞:因所需要的临界资源被占用而导致等待的线程挂起,这种情况就是阻塞。
非阻塞:强调没有一个可以妨碍其他线程执行,所有的线程都会尝试不断向前执行。
线程饥饿:只一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行
(一)Java语法
1.实现多线程方法:
- 继承Thread类。并重写run()方法,然后调用Thread实例的start()方法。考虑到Java的单继承特性,此方式有局限。
//继承Thread类,并重写run方法
class A extends Thread{
@Override
public void run(){
…… //多线程任务
}
}
Thread a=rew A();
a.start(); //开启线程,运行线程的run方法
- 实现runnable接口的run()方法,然后将实例传入到thread中,实际业务中同城使用此方式。
class B implements Runnable{
@Override
public void run(){
…… //多线程任务
}
}
Thread th=new Thread(new B()); //通过Thread的构造方法传入Runnable实例。
th.start(); //开启线程,调用Runnable.run()方法
默认的Thread.run()方法是判断如何运行线程任务的:
public void run(){
if(target!=null){
target.run();
}
}
2.线程安全
- 使用Thread.stop()方式停止线程,synchronized同步代码块会被立即停止,这样会导致数据不一致性发生,解决办法是自定义线程停止方法,让synchronized代码块执行完毕再停止。
- Thread.interrupt()用于线程中断,但是如果在Thread.sleep()执行过程中中断,则sleep()会清除中断标志位,只有再次调用interrupt()才能够实现最终中断。
- wait()与notify()
两个方法都是属于Object类,wait使当前线程进入等待队列,notify随机唤醒等待队列中的某一线程,线程执行二者需要先获取对象锁,并使用对象锁执行这两个方法。
class A extends Thread{
public void run(){
synchronized(object){ //使用对象锁
……;
object.wait();
……
}
}
}
class B extends Thread{
public void run(){
synchronized(object){ //使用对象锁
object.notify();
}
}
}
- join()方法:join方法将线程加入到当前线程执行,等待加入的线程执行完毕后才继续执行当前线程。
class A{
public static void main(String[] args){
Thread th=new Thread();
th.start();
th.join();
System.out.println("main线程执行结束"); //当th线程执行结束后才会继续执行
}
}
- 关键字synchronized:对同步的代码加锁,实现线程间的同步。注意多个线程必须获得同一对象锁才能够实现同步。
指定加锁对象:对给定加锁对象,进入同步代码前要获得给定对象的锁。
直接用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例锁。
直接作用于静态方法:相当于给当前类加锁,进入同步代码块前要获得当前类的锁。