JUC详解3
8锁问题
1、标准情况,两个线程是先发消息还是,先打电话? 先发消息再打电话
import java.util.concurrent.TimeUnit;
/**
* @Description 8锁现象
* 1、标准情况,两个线程是先发消息还是,先打电话? 先发消息再打电话
* 2、让发消息睡4秒,两个线程是先发消息还是,先打电话? 还是先发消息再打电话;为什么?
* @Author cai feifei
*/
public class Lock8 {
public static void main(String[] args) {
Qq qq = new Qq();
new Thread(()->{
qq.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
qq.callQq();
},"B").start();
}
}
class Qq{
public synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("使用qq发消息");
}
public synchronized void callQq(){
System.out.println("使用qq打电话");
}
}
- 因为锁的存在
- synchronized锁的对象是方法的调用者,两个方法用的同一把锁;谁先拿到锁,谁就先执行
3、添加一个普通方法,两个线程是先发消息,还是先发hello?
import java.util.concurrent.TimeUnit;
/**
* @Description
* 3、添加一个普通方法,两个线程是先发消息,还是先发hello? 先发消息再发hello?真实:发hello在发消息
* @Author cai feifei
*/
public class Lock2 {
public static void main(String[] args) {
Qq2 qq = new Qq2();
new Thread(()->{
qq.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
qq.sayHello();
},"B").start();
}
}
class Qq2{
/**
* synchronized锁的对象是方法的调用者,两个方法用的同一把锁;谁先拿到锁,谁就先执行
*/
public synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("使用qq发消息");
}
public synchronized void callQq(){
System.out.println("使用qq打电话");
}
/**
* 普通方法,没有锁,不受锁的影响
*/
public void sayHello(){
System.out.println("Hello!");
}
}
4、两个qq(对象),两个同步方法,两个线程是先发消息还是,先打电话?
package com.fly.juc.lock;
import java.util.concurrent.TimeUnit;
/**
* @Description
* 4、两个qq(对象),两个同步方法,两个线程是先发消息还是,先打电话?先打电话,在发短信
* @Author cai feifei
*/
public class Lock2 {
public static void main(String[] args) {
Qq2 qq2 = new Qq2();
Qq4 qq4 = new Qq4();
new Thread(()->{
qq2.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
qq4.callQq();
},"B").start();
}
}
class Qq2{
/**
* synchronized锁的对象是方法的调用者,两个方法用的同一把锁;谁先拿到锁,谁就先执行
*/
public synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("使用qq发消息");
}
public synchronized void callQq(){
System.out.println("使用qq打电话");
}
/**
* 普通方法,没有锁,不受锁的影响
*/
public void sayHello(){
System.out.println("Hello!");
}
}
class Qq4{
/**
* synchronized锁的对象是方法的调用者,两个方法用的同一把锁;谁先拿到锁,谁就先执行
*/
public synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("使用qq发消息");
}
public synchronized void callQq(){
System.out.println("使用qq打电话");
}
/**
* 普通方法,没有锁,不受锁的影响
*/
public void sayHello(){
System.out.println("Hello!");
}
}
5、增加2个静态同步方法,一个对象,两个线程是先发消息还是,先打电话?
package com.fly.juc.lock;
import java.util.concurrent.TimeUnit;
/**
* @Description
* 5、增加2个静态同步方法,一个对象,两个线程是先发消息还是,先打电话? 先发消息再打电话;两个对象呢?先发消息再打电话;
* 6、增加2个静态同步方法,两个对象,两个线程是先发消息还是,先打电话? 先发消息再打电话;两个对象呢?先发消息再打电话;
* @Author cai feifei
*/
public class Lock3 {
public static void main(String[] args) {
Qq3 qq3 = new Qq3();
Qq3 qq4 = new Qq3();
new Thread(()->{
qq3.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
qq4.callQq();
},"B").start();
}
}
class Qq3{
/**
* synchronized锁的对象是方法的调用者
* static类一加载就执行,所以此时锁的的Qq3的class;一个类的class全局也是唯一的
*/
public static synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("使用qq发消息");
}
//静态同步方法
public static synchronized void callQq(){
System.out.println("使用qq打电话");
}
}
7如果此时再增加一个普通的synchronized方法,是哪个先执行?
import java.util.concurrent.TimeUnit;
/**
* @Description
* 7、在5的基础上增加一个普通同步方法,两个对象,两个线程是先发消息还是,先发hello?先发hello
* 8、两个对象,一个静态同步方法,一个普通同步方法,两个线程是先发消息还是,先发hello?先发hello
* @Author cai feifei
*/
public class lock4 {
public static void main(String[] args) {
Qq6 qq6 = new Qq6();
Qq6 qq61 = new Qq6();
new Thread(()->{
qq6.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
qq61.sayHello();
},"B").start();
}
}
class Qq6{
//静态同步方法锁的是类
public static synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("使用qq发消息");
}
//静态同步方法
public static synchronized void callQq(){
System.out.println("使用qq打电话");
}
//普通同步方法锁的是对象
public synchronized void sayHello(){
System.out.println("Hello!");
}
}
总结:
new this 锁的是具体对象
static Class锁的是整个类的模板
在我们编写多线程程序得时候,只需要搞明白这个到底锁的是什么就不会出错了!
上一篇:JUC详解2——生产者消费者
下一篇:JUC详解4——集合相关