/** * @author tangquanbin * @date 2018/11/26 21:12 */ public class Service2 { /** * 同步方法 */ public synchronized void printService() { System.out.println(Thread.currentThread().getName() + " " + "start printService thread" ); try { TimeUnit.MILLISECONDS.sleep( 5000 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + "printService end " ); } /** * 同步方法 */ public synchronized void printServiceOther() { System.out.println(Thread.currentThread().getName() + " " + "start printServiceOther thread" ); try { TimeUnit.MILLISECONDS.sleep( 5000 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + "printServiceOther end " ); } /** * 非同步方法 */ public void printServiceNotSynchronized() { System.out.println(Thread.currentThread().getName() + " " + "start printServiceNotSynchronized thread" ); try { TimeUnit.MILLISECONDS.sleep( 5000 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + "printServiceNotSynchronized end " ); } } |
线程A
? public class Syn2ThreadA extends Thread{ private Service2 service; public Syn2ThreadA(Service2 service) { this .service = service; } @Override public void run() { super .run(); service.printService(); } } |
线程B
? public class Syn2ThreadB extends Thread{ private Service2 service; public Syn2ThreadB(Service2 service) { this .service = service; } @Override public void run() { super .run(); service.printServiceNotSynchronized(); } } |
线程C
? public class Syn2ThreadC extends Thread{ private Service2 service; public Syn2ThreadC(Service2 service) { this .service = service; } @Override public void run() { super .run(); service.printServiceOther(); } } |
测试方法:
? public class Syn2Test { public static void main(String[] args) { Service2 service = new Service2(); //Syn2ThreadA调用了同步方法 Syn2ThreadA threadA = new Syn2ThreadA(service); threadA.setName( "threadA" ); //Syn2ThreadB调用非同步 Syn2ThreadB threadB = new Syn2ThreadB(service); threadB.setName( "threadB" ); //Syn2ThreadC调用了同步方法 Syn2ThreadC threadC = new Syn2ThreadC(service); threadC.setName( "threadC" ); threadA.start(); threadB.start(); threadC.start(); } } |
public class Fruit { public synchronized void dosomething(){ System.out.println( "printFruit" ); } } |
子类
? public class Apple extends Fruit { @Override public synchronized void dosomething() { super .dosomething(); System.out.println( "apple" ); } } |
3.死锁
那什么是死锁呢?
下面是维基百科对死锁的定义:
死锁(英语:Deadlock),又译为死结,计算机科学名词。当两个以上的运算单元,双方都在等待对方停止运行,以获取系统资源,但是没有一方提前退出时,就称为死锁。 死锁的四个条件是: 禁止抢占 no preemption - 系统资源不能被强制从一个进程中退出 持有和等待 hold and wait - 一个进程可以在等待时持有系统资源 互斥 mutual exclusion - 只有一个进程能持有一个资源 循环等待 circular waiting - 一系列进程互相持有其他进程所需要的资源 死锁只有在这四个条件同时满足时出现。预防死锁就是至少破坏这四个条件其中一项,即破坏“禁止抢占”、破坏“持有等待”、破坏“资源互斥”和破坏“循环等待”。 下面这张图片描述了死锁情况:编码说明:
? /** * @author tangquanbin * @date 2018/11/26 22:37 */ public class TestDeadlock {
static final String resource1 = "resource1" ; static final String resource2 = "resource2" ; static class ThreadA extends Thread { @Override public void run() { synchronized (resource1) { System.out.println( "ThreadA: locked resource 1" ); try { TimeUnit.MILLISECONDS.sleep( 200 ); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resource2) { System.out.println( "ThreadA: locked resource 2" ); } } } } static class ThreadB extends Thread { @Override public void run() { synchronized (resource2) { System.out.println( "ThreadB: locked resource 2" ); try { TimeUnit.MILLISECONDS.sleep( 200 ); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (resource1) { System.out.println( "ThreadB: locked resource 1" ); } } } } public static void main(String[] args) { ThreadA threadA = new ThreadA(); threadA.setName( "====ThreadA====" ); ThreadB threadB = new ThreadB(); threadB.setName( "====ThreadB====" ); threadA.start(); threadB.start(); } } |
运行会产生死锁情况。
4.追踪、分析死锁发生
死锁检查方法,命令窗口运行: 1、jps 2、jstack -l 端口 //-l 选项用于打印锁的附加信息 下面是部分死锁信息: 死锁只有在这四个条件同时满足时出现。预防死锁就是至少破坏这四个条件其中一项,即破坏“禁止抢占”、破坏“持有等待”、破坏“资源互斥”和破坏“循环等待”。