前言
首先需要先了解synchronized具体的使用方法
接着认识两个概念:
1.锁池
所有需要竞争同步锁的线程都会放在锁池当中,如果当前对象的锁已经被其中一个线程得到,则其他线程需要在这个锁池进行等待,当之前的线程释放同步锁后,锁池中的所有线程都会去竞争同步锁,当某个线程得到后会进入就绪队列进行等待cpu资源分配。
2.等待池
当我们调用wait()方法后,线程会放到等待池当中,等待池的线程是不会去竞争同步锁。只有调用了notify()或notifyAll()后等待池的线程才会开始去竞争锁,notify()是随机从等待池选出一个线程放到锁池,而notifyAll()是将等待池的所有线程放到锁池当中
区别
1.sleep()方法
在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。sleep()使当前线程进入阻塞状态,在指定时间内不会执行。sleep()会指定休眠时间,线程休眠的时候会大于或者等于该休眠时间,当时间过后该线程会由“阻塞状态”编程“就绪状态”。
注意:sleep方法只是让出了cpu的执行权,并不会释放同步资源锁。
2.yield()方法
yield()方法和sleep()方法类似,也不会释放“锁标志”,区别在于,它没有参数,yield()的作用是让步,它能够让当前线程从“运行状态”进入到“就绪状态”,从而让其他等待线程获取执行权,但是不能保证在当前线程调用yield()之后,其他线程就一定能获得执行权,也有可能是当前线程又回到“运行状态”继续运行。
3.join()方法
join()方法会使当前调用的线程等待调用join()方法的线程结束后才能继续执行,例如当前进行的进行的线程是a,在调用b.join()方法后,a线程会等待b线程执行完毕或中断线程后a才会继续执行。
public class TestJoin {
public static void main(String[] args) {
Thread thread = new Thread(new JoinDemo());
thread.start();
for (int i = 0; i < 20; i++) {
System.out.println("主线程第" + i + "次执行!");
if (i >= 2)
try {
// t1线程合并到主线程中,主线程停止执行过程,转而执行t1线程,直到t1执行完毕后继续。
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class JoinDemo implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("线程1第" + i + "次执行!");
}
}
}
结果如下
4.wait()方法
- wait()必须在synchronized 修饰的同步代码块中调用
- wait()会释放cpu资源和释放同步锁(类锁和对象锁)
- 调用wait()后必须调用notify()或notifyAll()后线程才会从等待池进入到锁池,当我们的线程竞争得到同步锁后就会重新进入绪状态等待cpu资源分配
- wait()是Object类的方法
Object.wait()和Thread.sleep()都可以让程序等待若干时间,区别在于sleep()方法不会释放对象锁,而wait会释放锁
public class Demo{
final static Object person =new Object();
public static class T1 extends Thread{
public void run(){
synchronized (person){
System.out.println(System.currentTimeMillis()+"T1 come");
try{
System.out.println(System.currentTimeMillis()+"T1 wait");
person.wait();
}catch (InterruptedException r){
r.getStackTrace();
}
System.out.println(System.currentTimeMillis()+"T1 over");
}
}
}
public static class T2 extends Thread{
public void run(){
synchronized (person){
System.out.println(System.currentTimeMillis()+"T2 come");
person.notify();
System.out.println(System.currentTimeMillis()+"T2 over");
try{
Thread.sleep(2000);
}catch (InterruptedException r){
r.getStackTrace();
}
}
}
}
public static void main(String args[]){
try{
Thread thread1=new T1();
Thread thread2=new T2();
thread1.start();
thread2.start();
}catch (Exception e){
e.printStackTrace();
}
}
}
结果如下
来源:CSDN
作者:e电动小马达e
链接:https://blog.csdn.net/weixin_42046829/article/details/104476576