基本介绍:
Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。
主要作用:
- 修饰普通方法
- 修饰静态方法
- 修饰代码块
代码演示:
1.无Synchronized修饰
public class SyTestDemo {
public void methods1(){
System.out.println("methods1.start..");
try {
System.out.println("methods1.excute..");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("methods1.end..");
}
public void methods2(){
System.out.println("methods2.start.." );
try {
System.out.println("methods2.excute..");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("methods2.end..");
}
public static void main(String[] args) {
SyTestDemo testDemo = new SyTestDemo();
new Thread(new Runnable() {
@Override
public void run() {
testDemo.methods1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
testDemo.methods2();
}
}).start();
}
}
结果:
可以看出线程2在线程1结束前先结束。没有达到线程1运行完然后线程2在运行的目的。
2.修饰普通方法
代码演示
public class SyTestDemo2 {
//方法块1
public synchronized void methods1(){
System.out.println("methods1.start..");
try {
System.out.println("methods1.excute..");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("methods1.end..");
}
//方法块2
public synchronized void methods2(){
System.out.println("methods2.start..");
try {
System.out.println("methods2.excute..");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("methods2.end..");
}
public static void main(String[] args) {
SyTestDemo2 syTestDemo2 = new SyTestDemo2();
new Thread(new Runnable() {
@Override
public void run() {
syTestDemo2.methods1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
syTestDemo2.methods2();
}
}).start();
}
}
结果:
可以看出结果中是线程1先执行完然后线程2再完成。没有并发执行的情况产生。
3.修饰静态方法
代码演示:
public class SyTestDemo2 {
//静态方法1
public static synchronized void methods1(){
System.out.println("methods1.start..");
try {
System.out.println("methods1.excute..");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("methods1.end..");
}
//静态方法2
public static synchronized void methods2(){
System.out.println("methods2.start..");
try {
System.out.println("methods2.excute..");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("methods2.end..");
}
public static void main(String[] args) {
SyTestDemo2 syTestDemo2 = new SyTestDemo2();
new Thread(new Runnable() {
@Override
public void run() {
syTestDemo2.methods1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
syTestDemo2.methods2();
}
}).start();
}
}
结果:
修饰静态方法相当于修饰类。因为静态方法是类的方法而不是对象的方法。所以输出结果依旧是线程1先执行完,然后线程2执行完,没有并发执行。
4.修饰对象。
public class SyTestDemo3 {
//方法块1
public void methods1(){
System.out.println("methods1.start..");
synchronized (this){
System.out.println("methods1.excute..");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("methods1.end..");
}
//方法块2
public void methods2(){
System.out.println("methods2.start..");
synchronized (this){
System.out.println("methods2.excute..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("method2.end..");
}
public static void main(String[] args) {
SyTestDemo3 syTestDemo3 = new SyTestDemo3();
new Thread(new Runnable() {
@Override
public void run() {
syTestDemo3.methods1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
syTestDemo3.methods2();
}
}).start();
}
}
结果:
可以从结果中看出:虽然线程1和线程2都进入方法执行。但是线程2在进入同步块之前,需要等待线程1中同步块执行完成。
参考博客:Sychronized的学习和底层实现