例子一:一个对象,两个加锁方法
下面代码运行结果是先输出打电话还是发短信
public class Test1 {
public static void main(String[] args) {
Phone phone= new Phone();
//这里的->是lambda表达式的写法
new Thread(()-> {
phone.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone{
public synchronized void sendMessage(){
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
例子二:在例子一的基础上让第一个加锁方法睡眠4秒再执行
下面代码运行结果是先输出打电话还是发短信
public class Test1 {
public static void main(String[] args) {
Phone phone= new Phone();
//这里的->是lambda表达式的写法
new Thread(()-> {
phone.sendMessage();
},"A").start();
//捕获
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone{
//synchronized 锁的对象是方法的调用者
//两个方法调用的是同个锁即Phone,说先获取到就谁先输出
public synchronized void sendMessage(){
try {
//睡眠4秒再执行
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
//synchronized 锁的对象是方法的调用者
public synchronized void call(){
System.out.println("打电话");
}
}
例子三:一个普通方法hello和一个加锁的方法
下面代码运行结果是先输出你好还是发短信
public class Test2 {
public static void main(String[] args) {
Phone2 phone= new Phone2();
//这里的->是lambda表达式的写法
new Thread(()-> {
phone.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.hello();
},"B").start();
}
}
class Phone2{
public synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
//这里没有锁,不是同步方法,不受锁的影响
public void hello(){
System.out.println("你好");
}
}
例子四:两个对象,两个加锁方法
下面代码运行结果是先输出打电话还是发短信
//两个对象,两个同步方法,先打电话后发短信
public class Test2 {
public static void main(String[] args) {
//两个对象
Phone2 phone1= new Phone2();
Phone2 phone2= new Phone2();
//这里的->是lambda表达式的写法
new Thread(()-> {
phone1.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
class Phone2{
public synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
例子五:一个对象,两个static加锁方法
下面代码运行结果是先输出打电话还是发短信
public class Test3 {
public static void main(String[] args) {
Phone3 phone= new Phone3();
//这里的->是lambda表达式的写法
new Thread(()-> {
phone.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone3{
//static静态方法
//类一加载就有了 锁的class类
//所以此时锁的是同一个锁
public static synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call(){
System.out.println("打电话");
}
}
例子六:两个对象,两个static加锁方法
下面代码运行结果是先输出打电话还是发短信
public class Test3 {
public static void main(String[] args) {
//两个对象的class类模板只有一个,static锁的是class
Phone3 phone1= new Phone3();
Phone3 phone2= new Phone3();
//这里的->是lambda表达式的写法
new Thread(()-> {
phone1.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
class Phone3{
//static静态方法
//类一加载就有了 锁的class类
//所以此时锁的是同一个锁
public static synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call(){
System.out.println("打电话");
}
}
例子七:一个对象,一个static加锁方法,一个普通加锁同步方法
下面代码运行结果是先输出打电话还是发短信
public class Test4 {
public static void main(String[] args) {
Phone4 phone= new Phone4();
//这里的->是lambda表达式的写法
new Thread(()-> {
phone.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone4{
//静态同步方法,锁的类模板
public static synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
//普通同步方法,锁的调用方法
public synchronized void call(){
System.out.println("打电话");
}
}
例子八:两个对象,一个static加锁方法,一个普通加锁同步方法
下面代码运行结果是先输出打电话还是发短信
public class Test4 {
public static void main(String[] args) {
Phone4 phone1= new Phone4();
Phone4 phone2= new Phone4();
//这里的->是lambda表达式的写法
new Thread(()-> {
phone1.sendMessage();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
class Phone4{
//静态同步方法,锁的类模板
public static synchronized void sendMessage(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
//普通同步方法,锁的调用方法
public synchronized void call(){
System.out.println("打电话");
}
}
例子一运行结果:发短信 打电话
例子二运行结果:等待4秒后输出 发短信 打电话
例子三运行结果:先输出你好 后输出 发短信
例子四运行结果:先输出打电话 再发短信
例子五运行结果:先发短信后打电话
例子六运行结果:先发短信后打电话
例子七运行结果:先打电话,后发短信
例子八运行结果:先打电话,后发短信
小结
static synchronized 锁的是class
synchronized 锁的是对象
谁先获取到对象谁就先执行
声明:本文为学习狂神说java的juc并发编程所做的笔记,狂神说javajuc并发编程地址:https://www.bilibili.com/video/BV1B7411L7tE?p=11
转载:https://blog.csdn.net/weixin_42369886/article/details/106000740