这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
分享:技术:多线程:多线程编程核心技术整理 [2016/06/19 14:05] gxx |
分享:技术:多线程:多线程编程核心技术整理 [2016/06/19 18:16] (当前版本) gxx |
||
---|---|---|---|
行 1059: | 行 1059: | ||
[Thead][守护线程]打印count=9 | [Thead][守护线程]打印count=9 | ||
[main][非守护线程] 结束,则[守护线程]也自动结束 | [main][非守护线程] 结束,则[守护线程]也自动结束 | ||
+ | </code> | ||
+ | ===== 对象及变量的并发访问 ===== | ||
+ | ==== synchronized同步方法 ==== | ||
+ | === 方法内变量为线程安全 === | ||
+ | <code java NumProcess.java> | ||
+ | package com.gxx.threads.study.test15; | ||
+ | |||
+ | /** | ||
+ | * 数字处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class NumProcess { | ||
+ | /** | ||
+ | * 处理逻辑 | ||
+ | */ | ||
+ | public void process(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入process~"); | ||
+ | /** | ||
+ | * 方法内变量 | ||
+ | */ | ||
+ | int num; | ||
+ | /** | ||
+ | * 根据线程名称走不同分支 | ||
+ | */ | ||
+ | if(Thread.currentThread().getName().equals("线程A")){ | ||
+ | num = 100; | ||
+ | try { | ||
+ | Thread.sleep(2000);//睡眠2秒 | ||
+ | } catch (InterruptedException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } else { | ||
+ | num = 200; | ||
+ | } | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "] num=" + num); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MyThead.java> | ||
+ | package com.gxx.threads.study.test15; | ||
+ | |||
+ | /** | ||
+ | * 自定义线程类 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MyThread extends Thread { | ||
+ | /** | ||
+ | * 数字处理器 | ||
+ | */ | ||
+ | NumProcess numProcess; | ||
+ | |||
+ | /** | ||
+ | * 构造方法 | ||
+ | * @param name | ||
+ | * @param numProcess | ||
+ | */ | ||
+ | public MyThread(String name, NumProcess numProcess) { | ||
+ | this.setName(name); | ||
+ | this.numProcess = numProcess; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 覆盖run方法 | ||
+ | */ | ||
+ | @Override | ||
+ | public void run() { | ||
+ | numProcess.process(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java Test.java> | ||
+ | package com.gxx.threads.study.test15; | ||
+ | |||
+ | /** | ||
+ | * 测试类-测试方法内变量并发访问 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class Test { | ||
+ | /** | ||
+ | * main方法 | ||
+ | * @param args | ||
+ | */ | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println("main 开始"); | ||
+ | NumProcess numProcess = new NumProcess(); | ||
+ | MyThread threadA = new MyThread("线程A", numProcess); | ||
+ | MyThread threadB = new MyThread("线程B", numProcess); | ||
+ | threadA.start(); | ||
+ | threadB.start(); | ||
+ | System.out.println("main 结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 输出 | ||
+ | <code> | ||
+ | main 开始 | ||
+ | main 结束 | ||
+ | [线程A]进入process~ | ||
+ | [线程B]进入process~ | ||
+ | [线程B] num=200 | ||
+ | [线程A] num=100 | ||
+ | </code> | ||
+ | === 实例变量非线程安全 === | ||
+ | <code java NumProcess.java> | ||
+ | package com.gxx.threads.study.test16; | ||
+ | |||
+ | /** | ||
+ | * 数字处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class NumProcess { | ||
+ | /** | ||
+ | * 实例变量 | ||
+ | */ | ||
+ | int num; | ||
+ | /** | ||
+ | * 处理逻辑 | ||
+ | */ | ||
+ | public void process(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入process~"); | ||
+ | /** | ||
+ | * 根据线程名称走不同分支 | ||
+ | */ | ||
+ | if(Thread.currentThread().getName().equals("线程A")){ | ||
+ | num = 100; | ||
+ | try { | ||
+ | Thread.sleep(2000);//睡眠2秒 | ||
+ | } catch (InterruptedException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } else { | ||
+ | num = 200; | ||
+ | } | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "] num=" + num); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MyThead.java> | ||
+ | package com.gxx.threads.study.test16; | ||
+ | |||
+ | /** | ||
+ | * 自定义线程类 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MyThread extends Thread { | ||
+ | /** | ||
+ | * 数字处理器 | ||
+ | */ | ||
+ | NumProcess numProcess; | ||
+ | |||
+ | /** | ||
+ | * 构造方法 | ||
+ | * @param name | ||
+ | * @param numProcess | ||
+ | */ | ||
+ | public MyThread(String name, NumProcess numProcess) { | ||
+ | this.setName(name); | ||
+ | this.numProcess = numProcess; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 覆盖run方法 | ||
+ | */ | ||
+ | @Override | ||
+ | public void run() { | ||
+ | numProcess.process(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java Test.java> | ||
+ | package com.gxx.threads.study.test16; | ||
+ | |||
+ | /** | ||
+ | * 测试类-测试实例变量并发访问 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class Test { | ||
+ | /** | ||
+ | * main方法 | ||
+ | * @param args | ||
+ | */ | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println("main 开始"); | ||
+ | NumProcess numProcess = new NumProcess(); | ||
+ | MyThread threadA = new MyThread("线程A", numProcess); | ||
+ | MyThread threadB = new MyThread("线程B", numProcess); | ||
+ | threadA.start(); | ||
+ | threadB.start(); | ||
+ | System.out.println("main 结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 输出 | ||
+ | <code> | ||
+ | main 开始 | ||
+ | main 结束 | ||
+ | [线程A]进入process~ | ||
+ | [线程B]进入process~ | ||
+ | [线程B] num=200 | ||
+ | [线程A] num=200 | ||
+ | </code> | ||
+ | === 实例变量非线程安全,synchronized同步 === | ||
+ | <code java NumProcess.java> | ||
+ | package com.gxx.threads.study.test17; | ||
+ | |||
+ | /** | ||
+ | * 数字处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class NumProcess { | ||
+ | /** | ||
+ | * 实例变量 | ||
+ | */ | ||
+ | int num; | ||
+ | /** | ||
+ | * 处理逻辑 | ||
+ | */ | ||
+ | public synchronized void process(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入process~"); | ||
+ | /** | ||
+ | * 根据线程名称走不同分支 | ||
+ | */ | ||
+ | if(Thread.currentThread().getName().equals("线程A")){ | ||
+ | num = 100; | ||
+ | try { | ||
+ | Thread.sleep(2000);//睡眠2秒 | ||
+ | } catch (InterruptedException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } else { | ||
+ | num = 200; | ||
+ | } | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "] num=" + num); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MyThead.java> | ||
+ | package com.gxx.threads.study.test17; | ||
+ | |||
+ | /** | ||
+ | * 自定义线程类 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MyThread extends Thread { | ||
+ | /** | ||
+ | * 数字处理器 | ||
+ | */ | ||
+ | NumProcess numProcess; | ||
+ | |||
+ | /** | ||
+ | * 构造方法 | ||
+ | * @param name | ||
+ | * @param numProcess | ||
+ | */ | ||
+ | public MyThread(String name, NumProcess numProcess) { | ||
+ | this.setName(name); | ||
+ | this.numProcess = numProcess; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 覆盖run方法 | ||
+ | */ | ||
+ | @Override | ||
+ | public void run() { | ||
+ | numProcess.process(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java Test.java> | ||
+ | package com.gxx.threads.study.test17; | ||
+ | |||
+ | /** | ||
+ | * 测试类-测试实例变量并发访问,synchronized同步 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class Test { | ||
+ | /** | ||
+ | * main方法 | ||
+ | * @param args | ||
+ | */ | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println("main 开始"); | ||
+ | NumProcess numProcess = new NumProcess(); | ||
+ | MyThread threadA = new MyThread("线程A", numProcess); | ||
+ | MyThread threadB = new MyThread("线程B", numProcess); | ||
+ | threadA.start(); | ||
+ | threadB.start(); | ||
+ | System.out.println("main 结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 输出 | ||
+ | <code> | ||
+ | main 开始 | ||
+ | main 结束 | ||
+ | [线程A]进入process~ | ||
+ | [线程A] num=100 | ||
+ | [线程B]进入process~ | ||
+ | [线程B] num=200 | ||
+ | </code> | ||
+ | === 多个对象多个锁 === | ||
+ | <code java NumProcess.java> | ||
+ | package com.gxx.threads.study.test18; | ||
+ | |||
+ | /** | ||
+ | * 数字处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class NumProcess { | ||
+ | /** | ||
+ | * 实例变量 | ||
+ | */ | ||
+ | int num; | ||
+ | /** | ||
+ | * 处理逻辑 | ||
+ | */ | ||
+ | public synchronized void process(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入process~"); | ||
+ | /** | ||
+ | * 根据线程名称走不同分支 | ||
+ | */ | ||
+ | if(Thread.currentThread().getName().equals("线程A")){ | ||
+ | num = 100; | ||
+ | try { | ||
+ | Thread.sleep(2000);//睡眠2秒 | ||
+ | } catch (InterruptedException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } else { | ||
+ | num = 200; | ||
+ | } | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "] num=" + num); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MyThead.java> | ||
+ | package com.gxx.threads.study.test18; | ||
+ | |||
+ | /** | ||
+ | * 自定义线程类 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MyThread extends Thread { | ||
+ | /** | ||
+ | * 数字处理器 | ||
+ | */ | ||
+ | NumProcess numProcess; | ||
+ | |||
+ | /** | ||
+ | * 构造方法 | ||
+ | * @param name | ||
+ | * @param numProcess | ||
+ | */ | ||
+ | public MyThread(String name, NumProcess numProcess) { | ||
+ | this.setName(name); | ||
+ | this.numProcess = numProcess; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 覆盖run方法 | ||
+ | */ | ||
+ | @Override | ||
+ | public void run() { | ||
+ | numProcess.process(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java Test.java> | ||
+ | package com.gxx.threads.study.test18; | ||
+ | |||
+ | /** | ||
+ | * 测试类-测试多个对象多个锁 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class Test { | ||
+ | /** | ||
+ | * main方法 | ||
+ | * @param args | ||
+ | */ | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println("main 开始"); | ||
+ | NumProcess numProcess1 = new NumProcess(); | ||
+ | MyThread threadA = new MyThread("线程A", numProcess1); | ||
+ | NumProcess numProcess2 = new NumProcess(); | ||
+ | MyThread threadB = new MyThread("线程B", numProcess2); | ||
+ | threadA.start(); | ||
+ | threadB.start(); | ||
+ | System.out.println("main 结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 输出 | ||
+ | <code> | ||
+ | main 开始 | ||
+ | main 结束 | ||
+ | [线程A]进入process~ | ||
+ | [线程B]进入process~ | ||
+ | [线程B] num=200 | ||
+ | [线程A] num=100 | ||
+ | </code> | ||
+ | === synchronized方法与锁对象 === | ||
+ | * 线程进synchronized方法获取锁,都是锁对象实例,其他线程可以进该实例其他不带synchronized的方法 | ||
+ | <code java MethodProcess.java> | ||
+ | package com.gxx.threads.study.test19; | ||
+ | |||
+ | /** | ||
+ | * 方法处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MethodProcess { | ||
+ | /** | ||
+ | * 方法A | ||
+ | */ | ||
+ | public synchronized void methodA(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入methodA~"); | ||
+ | try { | ||
+ | Thread.sleep(2000); | ||
+ | } catch (InterruptedException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]methodA结束"); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 方法B | ||
+ | */ | ||
+ | public void methodB(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入methodB~"); | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]methodB结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MyThead.java> | ||
+ | package com.gxx.threads.study.test19; | ||
+ | |||
+ | /** | ||
+ | * 自定义线程类 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MyThread extends Thread { | ||
+ | /** | ||
+ | * 方法处理器 | ||
+ | */ | ||
+ | MethodProcess methodProcess; | ||
+ | |||
+ | /** | ||
+ | * 构造方法 | ||
+ | * @param name | ||
+ | * @param methodProcess | ||
+ | */ | ||
+ | public MyThread(String name, MethodProcess methodProcess) { | ||
+ | this.setName(name); | ||
+ | this.methodProcess = methodProcess; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 覆盖run方法 | ||
+ | */ | ||
+ | @Override | ||
+ | public void run() { | ||
+ | if("线程A".equals(this.getName())){ | ||
+ | methodProcess.methodA(); | ||
+ | } else { | ||
+ | methodProcess.methodB(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java Test.java> | ||
+ | package com.gxx.threads.study.test19; | ||
+ | |||
+ | /** | ||
+ | * 测试类-测试synchronized方法与锁对象 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class Test { | ||
+ | /** | ||
+ | * main方法 | ||
+ | * @param args | ||
+ | */ | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println("main 开始"); | ||
+ | MethodProcess methodProcess = new MethodProcess(); | ||
+ | MyThread threadA = new MyThread("线程A", methodProcess); | ||
+ | MyThread threadB = new MyThread("线程B", methodProcess); | ||
+ | threadA.start(); | ||
+ | threadB.start(); | ||
+ | System.out.println("main 结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 输出 | ||
+ | <code> | ||
+ | main 开始 | ||
+ | main 结束 | ||
+ | [线程A]进入methodA~ | ||
+ | [线程B]进入methodB~ | ||
+ | [线程B]methodB结束 | ||
+ | [线程A]methodA结束 | ||
+ | </code> | ||
+ | * 线程A进synchronized的方法A,获取了锁,同时,线程B想进synchronized的方法B,得排队 | ||
+ | <code java MethodProcess.java> | ||
+ | package com.gxx.threads.study.test20; | ||
+ | |||
+ | /** | ||
+ | * 方法处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MethodProcess { | ||
+ | /** | ||
+ | * 方法A | ||
+ | */ | ||
+ | public synchronized void methodA(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入methodA~"); | ||
+ | try { | ||
+ | Thread.sleep(2000); | ||
+ | } catch (InterruptedException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]methodA结束"); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 方法B | ||
+ | */ | ||
+ | public synchronized void methodB(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入methodB~"); | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]methodB结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MyThead.java> | ||
+ | package com.gxx.threads.study.test20; | ||
+ | |||
+ | /** | ||
+ | * 自定义线程类 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MyThread extends Thread { | ||
+ | /** | ||
+ | * 方法处理器 | ||
+ | */ | ||
+ | MethodProcess methodProcess; | ||
+ | |||
+ | /** | ||
+ | * 构造方法 | ||
+ | * @param name | ||
+ | * @param methodProcess | ||
+ | */ | ||
+ | public MyThread(String name, MethodProcess methodProcess) { | ||
+ | this.setName(name); | ||
+ | this.methodProcess = methodProcess; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 覆盖run方法 | ||
+ | */ | ||
+ | @Override | ||
+ | public void run() { | ||
+ | if("线程A".equals(this.getName())){ | ||
+ | methodProcess.methodA(); | ||
+ | } else { | ||
+ | methodProcess.methodB(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java Test.java> | ||
+ | package com.gxx.threads.study.test20; | ||
+ | |||
+ | /** | ||
+ | * 测试类-测试synchronized方法与锁对象 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class Test { | ||
+ | /** | ||
+ | * main方法 | ||
+ | * @param args | ||
+ | */ | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println("main 开始"); | ||
+ | MethodProcess methodProcess = new MethodProcess(); | ||
+ | MyThread threadA = new MyThread("线程A", methodProcess); | ||
+ | MyThread threadB = new MyThread("线程B", methodProcess); | ||
+ | threadA.start(); | ||
+ | threadB.start(); | ||
+ | System.out.println("main 结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 输出 | ||
+ | <code> | ||
+ | main 开始 | ||
+ | main 结束 | ||
+ | [线程A]进入methodA~ | ||
+ | [线程A]methodA结束 | ||
+ | [线程B]进入methodB~ | ||
+ | [线程B]methodB结束 | ||
+ | </code> | ||
+ | === synchronized锁重入与异常释放锁 === | ||
+ | * 当前类中不同synchronized方法可以锁重入 | ||
+ | * 父子类中不同synchronized方法可以锁重入 | ||
+ | * 发生异常,立刻释放锁 | ||
+ | <code java MethodProcess.java> | ||
+ | package com.gxx.threads.study.test21; | ||
+ | |||
+ | /** | ||
+ | * 方法处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MethodProcess extends MethodProcessParent { | ||
+ | /** | ||
+ | * 方法A | ||
+ | */ | ||
+ | public synchronized void methodA(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入methodA~"); | ||
+ | methodB(); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 方法B | ||
+ | */ | ||
+ | public synchronized void methodB(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入methodB~"); | ||
+ | methodC(); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 方法C | ||
+ | */ | ||
+ | public synchronized void methodC(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入methodC~"); | ||
+ | super.methodD(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MethodProcessParent.java> | ||
+ | package com.gxx.threads.study.test21; | ||
+ | |||
+ | /** | ||
+ | * 方法处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MethodProcessParent { | ||
+ | /** | ||
+ | * 计数 | ||
+ | */ | ||
+ | int count = 0; | ||
+ | |||
+ | /** | ||
+ | * 方法D | ||
+ | */ | ||
+ | public synchronized void methodD(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入methodD~"); | ||
+ | while (true) { | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]打印count=" + count); | ||
+ | try { | ||
+ | Thread.sleep(1000); | ||
+ | } catch (InterruptedException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | if(++count == 5){ | ||
+ | count = 0; | ||
+ | throw new RuntimeException("手动抛出异常~"); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MyThead.java> | ||
+ | package com.gxx.threads.study.test21; | ||
+ | |||
+ | /** | ||
+ | * 自定义线程类 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MyThread extends Thread { | ||
+ | /** | ||
+ | * 方法处理器 | ||
+ | */ | ||
+ | MethodProcess methodProcess; | ||
+ | |||
+ | /** | ||
+ | * 构造方法 | ||
+ | * @param name | ||
+ | * @param methodProcess | ||
+ | */ | ||
+ | public MyThread(String name, MethodProcess methodProcess) { | ||
+ | this.setName(name); | ||
+ | this.methodProcess = methodProcess; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 覆盖run方法 | ||
+ | */ | ||
+ | @Override | ||
+ | public void run() { | ||
+ | methodProcess.methodA(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java Test.java> | ||
+ | package com.gxx.threads.study.test21; | ||
+ | |||
+ | /** | ||
+ | * 测试类-测试synchronized锁重入 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class Test { | ||
+ | /** | ||
+ | * main方法 | ||
+ | * @param args | ||
+ | */ | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println("main 开始"); | ||
+ | MethodProcess methodProcess = new MethodProcess(); | ||
+ | MyThread threadA = new MyThread("线程A", methodProcess); | ||
+ | threadA.start(); | ||
+ | MyThread threadB = new MyThread("线程B", methodProcess); | ||
+ | threadB.start(); | ||
+ | System.out.println("main 结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 输出 | ||
+ | <code> | ||
+ | main 开始 | ||
+ | main 结束 | ||
+ | [线程A]进入methodA~ | ||
+ | [线程A]进入methodB~ | ||
+ | [线程A]进入methodC~ | ||
+ | [线程A]进入methodD~ | ||
+ | [线程A]打印count=0 | ||
+ | [线程A]打印count=1 | ||
+ | [线程A]打印count=2 | ||
+ | [线程A]打印count=3 | ||
+ | [线程A]打印count=4 | ||
+ | [线程B]进入methodA~ | ||
+ | Exception in thread "线程A" java.lang.RuntimeException: 手动抛出异常~ | ||
+ | at com.gxx.threads.study.test21.MethodProcessParent.methodD(MethodProcessParent.java:27) | ||
+ | at com.gxx.threads.study.test21.MethodProcess.methodC(MethodProcess.java:29) | ||
+ | at com.gxx.threads.study.test21.MethodProcess.methodB(MethodProcess.java:21) | ||
+ | at com.gxx.threads.study.test21.MethodProcess.methodA(MethodProcess.java:13) | ||
+ | at com.gxx.threads.study.test21.MyThread.run(MyThread.java:28) | ||
+ | [线程B]进入methodB~ | ||
+ | [线程B]进入methodC~ | ||
+ | [线程B]进入methodD~ | ||
+ | [线程B]打印count=0 | ||
+ | [线程B]打印count=1 | ||
+ | [线程B]打印count=2 | ||
+ | [线程B]打印count=3 | ||
+ | [线程B]打印count=4 | ||
+ | Exception in thread "线程B" java.lang.RuntimeException: 手动抛出异常~ | ||
+ | at com.gxx.threads.study.test21.MethodProcessParent.methodD(MethodProcessParent.java:27) | ||
+ | at com.gxx.threads.study.test21.MethodProcess.methodC(MethodProcess.java:29) | ||
+ | at com.gxx.threads.study.test21.MethodProcess.methodB(MethodProcess.java:21) | ||
+ | at com.gxx.threads.study.test21.MethodProcess.methodA(MethodProcess.java:13) | ||
+ | at com.gxx.threads.study.test21.MyThread.run(MyThread.java:28) | ||
+ | </code> | ||
+ | === 同步不具有继承性 === | ||
+ | <code java MethodProcess.java> | ||
+ | package com.gxx.threads.study.test22; | ||
+ | |||
+ | /** | ||
+ | * 方法处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MethodProcess extends MethodProcessParent { | ||
+ | /** | ||
+ | * 处理 | ||
+ | */ | ||
+ | public void process(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入process~"); | ||
+ | try { | ||
+ | Thread.sleep(2000); | ||
+ | } catch (InterruptedException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]process结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MethodProcessParent.java> | ||
+ | package com.gxx.threads.study.test22; | ||
+ | |||
+ | /** | ||
+ | * 方法处理器 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MethodProcessParent { | ||
+ | /** | ||
+ | * 处理 | ||
+ | */ | ||
+ | public synchronized void process(){ | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]进入process~"); | ||
+ | try { | ||
+ | Thread.sleep(2000); | ||
+ | } catch (InterruptedException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | System.out.println("[" + Thread.currentThread().getName() + "]process结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java MyThead.java> | ||
+ | package com.gxx.threads.study.test22; | ||
+ | |||
+ | /** | ||
+ | * 自定义线程类 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class MyThread extends Thread { | ||
+ | /** | ||
+ | * 方法处理器 | ||
+ | */ | ||
+ | MethodProcess methodProcess; | ||
+ | |||
+ | /** | ||
+ | * 构造方法 | ||
+ | * @param name | ||
+ | * @param methodProcess | ||
+ | */ | ||
+ | public MyThread(String name, MethodProcess methodProcess) { | ||
+ | this.setName(name); | ||
+ | this.methodProcess = methodProcess; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * 覆盖run方法 | ||
+ | */ | ||
+ | @Override | ||
+ | public void run() { | ||
+ | methodProcess.process(); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | <code java Test.java> | ||
+ | package com.gxx.threads.study.test22; | ||
+ | |||
+ | /** | ||
+ | * 测试类-测试同步不具有继承性 | ||
+ | * @author Gxx | ||
+ | */ | ||
+ | public class Test { | ||
+ | /** | ||
+ | * main方法 | ||
+ | * @param args | ||
+ | */ | ||
+ | public static void main(String[] args) { | ||
+ | System.out.println("main 开始"); | ||
+ | MethodProcess methodProcess = new MethodProcess(); | ||
+ | MyThread threadA = new MyThread("线程A", methodProcess); | ||
+ | MyThread threadB = new MyThread("线程B", methodProcess); | ||
+ | threadA.start(); | ||
+ | threadB.start(); | ||
+ | System.out.println("main 结束"); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | 输出 | ||
+ | <code> | ||
+ | main 开始 | ||
+ | main 结束 | ||
+ | [线程B]进入process~ | ||
+ | [线程A]进入process~ | ||
+ | [线程B]process结束 | ||
+ | [线程A]process结束 | ||
</code> | </code> |