不啰嗦,我们直接开始!
代码:
public class SynchronizedObjectMethod implements Runnable {
static SynchronizedObjectMethod instance = new SynchronizedObjectMethod();
@Override
public void run() {
method();
}
public synchronized void method() {
System.out.println("对象锁的方法修饰符形式,我叫:" + Thread.currentThread().getName());
try {
System.out.println(Thread.currentThread().getName() + " 休眠3秒");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束");
}
public static void main(String[] args) {
//两个线程访问一个对象的同步方法,对象为instance实例
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("fininshed");
}
}
运行结果:
对象锁的方法修饰符形式,我叫:Thread-0
Thread-0 休眠3秒
Thread-0运行结束
对象锁的方法修饰符形式,我叫:Thread-1
Thread-1 休眠3秒
Thread-1运行结束
fininshed
解析:需要争抢同一把锁this,所以顺序执行。
代码:
public class SynchronizedTwoThreadToTwoObject implements Runnable {
static SynchronizedTwoThreadToTwoObject instance1 = new SynchronizedTwoThreadToTwoObject();
static SynchronizedTwoThreadToTwoObject instance2 = new SynchronizedTwoThreadToTwoObject();
@Override
public void run() {
// 当前对象作为锁
synchronized (this) {
System.out.println("我是对象锁的代码块形式,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束");
}
}
public static void main(String[] args) {
//两个线程访问的是两个对象的同步方法,两个对象一个为instance1,另一个为instance2
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("fininshed");
}
}
运行结果:
我是对象锁的代码块形式,我叫Thread-0
我是对象锁的代码块形式,我叫Thread-1
Thread-1运行结束
Thread-0运行结束
fininshed
解析:并行处理,不受干扰,锁的实例不是同一个。
代码:
public class SynchronizedClassStatic implements Runnable {
static SynchronizedClassStatic instance1=new SynchronizedClassStatic();
static SynchronizedClassStatic instance2=new SynchronizedClassStatic();
@Override
public void run() {
method();
}
public static synchronized void method(){
System.out.println("我是类锁的一种形式,我叫"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程结束");
}
public static void main(String[] args){
//两个线程访问synchronized的静态方法
Thread t1=new Thread(instance1);
Thread t2=new Thread(instance2);
t1.start();
t2.start();
while (t1.isAlive()||t2.isAlive()){
}
System.out.println("fininshed");
}
}
运行结果:
我是类锁的一种形式,我叫Thread-0
Thread-0线程结束
我是类锁的一种形式,我叫Thread-1
Thread-1线程结束
fininshed
解析:对应的锁是同一把,一个一个的顺序执行。
代码:
public class SynchronizedYesOrNo implements Runnable {
static SynchronizedYesOrNo instance=new SynchronizedYesOrNo();
public static void main(String[] args) {
Thread th1=new Thread(instance);
Thread th2=new Thread(instance);
th1.start();
th2.start();
while(th1.isAlive()||th2.isAlive()){
}
System.out.println("finished");
}
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")){
method1();
}else{
method2();
}
}
public synchronized void method1(){
System.out.println("我是加了同步的方法"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"结束");
}
public synchronized static void method2(){
System.out.println("我是没加了同步的方法"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"结束");
}
}
运行结果:
我是加了同步的方法Thread-0
我是没加了同步的方法Thread-1
Thread-0结束
Thread-1结束
finished
解析:同步方法不会出现并发问题,非同步方法不会受到影响,出现并发问题。
代码:
public class SynchronizedDifferentMethod implements Runnable {
static SynchronizedDifferentMethod instance=new SynchronizedDifferentMethod();
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")){
method1();
}else {
method2();
}
}
public synchronized void method1(){
System.out.println("我是加锁的方法"+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程执行结束");
}
public synchronized void method2(){
System.out.println("我也是加锁的方法"+Thread.currentThread().getName()+"线程执行结束");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程执行结束");
}
public static void main(String[] args) throws InterruptedException{
Thread t1=new Thread(instance);
Thread t2=new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive()||t2.isAlive()){}
System.out.println("fininshed");
}
}
运行结果:
我是加锁的方法Thread-0
Thread-0线程执行结束
我也是加锁的方法Thread-1线程执行结束
Thread-1线程执行结束
fininshed
解析:拿到的是this锁,所以还是会受影响,串行执行。
代码:
public class SynchronizedStaticAndNormal implements Runnable {
static SynchronizedStaticAndNormal instance=new SynchronizedStaticAndNormal();
@Override
public void run() {
if(Thread.currentThread().getName().equals("Thread-0")){
method1();
}else {
method2();
}
}
public synchronized static void method1(){
System.out.println("我是加锁的静态方法1 "+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程执行结束");
}
public synchronized void method2(){
System.out.println("我是加锁的非静态方法2 "+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"线程执行结束");
}
public static void main(String[] args) throws InterruptedException{
Thread t1=new Thread(instance);
Thread t2=new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive()||t2.isAlive()){}
System.out.println("fininshed");
}
}
运行结果:
我是加锁的静态方法1 Thread-0
我是加锁的非静态方法2 Thread-1
Thread-1线程执行结束
Thread-0线程执行结束
fininshed
解析:method1锁的是.class对象,method2锁的是this对象,锁不一样,没有冲突,并行执行。
代码:
public class SynchronizedException implements Runnable {
static SynchronizedException instance = new SynchronizedException();
@Override
public void run() {
if (Thread.currentThread().getName().equals("Thread-0")) {
method1();
} else {
method2();
}
}
public synchronized void method1() {
/*
// 抛出Exception
System.out.println("我是加锁的静态方法1" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
//异常抛出后,JVM会自动帮你释放锁,不需要自己手动释放锁。
throw new Exception();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "线程执行结束");
*/
// 抛出RuntimeException
System.out.println("我是加锁的静态方法1" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
//异常抛出后,JVM会自动帮你释放锁,不需要自己手动释放锁。
throw new RuntimeException();
// System.out.println(Thread.currentThread().getName() + "线程执行结束");
}
public synchronized void method2() {
System.out.println("我也是加锁的非静态方法2" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "线程执行结束");
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("fininshed");
}
}
运行结果:
我是加锁的静态方法1Thread-0
Exception in thread "Thread-0" java.lang.RuntimeException
at com.interview.javabasic.thread.a0914.SynchronizedException.method1(SynchronizedException.java:50)
at com.interview.javabasic.thread.a0914.SynchronizedException.run(SynchronizedException.java:16)
at java.lang.Thread.run(Thread.java:748)
我也是加锁的非静态方法2Thread-1
Thread-1线程执行结束
fininshed
解析:方法抛出异常后,会释放锁。
参考文章:
- (Synchronized)多线程访问同步方法的七种具体情况
- Java 多线程访问同步方法的七种情况
不啰嗦,文章结束,期待三连!