实验java中synchronized的使用
1 首先我们创建一个测试类TestSync
在TestSync中创建一个内部类Worker实现Runnable接口
class Worker implements Runnable{ int index = 1; @Override public void run() { int runIndex = index; index++; System.out.println("非同步块,顺序执行"); try { if(runIndex == 1){ Thread.sleep(3000); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("线程计数, 第 "+runIndex+"次执行"); } }
2 再写一个 print方法,此方法创建一个worker对象,并使用两个线程去执行
public void print(){ Worker worker = new Worker(); new Thread(worker).start(); new Thread(worker).start(); }
3 添加main方法 执行 print方法
public static void main(String[] args) throws Exception{ TestSync testSync = new TestSync(); testSync.print(); }
4完整的 类代码如下:
package com.jshand.thread; public class TestSync { public void print() { Worker worker = new Worker(); new Thread(worker).start(); new Thread(worker).start(); } class Worker implements Runnable { int index = 1; @Override public void run() { int runIndex = index; index++; System.out.println("非同步块,顺序执行"); try { if (runIndex == 1) { Thread.sleep(3000); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("线程计数, 第 " + runIndex + "次执行"); } } public static void main(String[] args) throws Exception { TestSync testSync = new TestSync(); testSync.print(); } }
5 执行后 打印的结果如下:
非同步块,顺序执行
非同步块,顺序执行
线程计数, 第 2次执行
//执行此处时会等待大约3秒钟后才执行下面一句话,并且发现线程第二次的会先于第一次的执行完。
线程计数, 第 1次执行
6 下面 我们将Worker线程类 的run方法改造一下 ,添加一个同步块,也就是synchronized 块 run方法如下
public void run() { int runIndex = index; index++; System.out.println("非同步块,顺序执行"); synchronized (this) { try { if(runIndex == 1){ Thread.sleep(3000); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("线程计数, 第 "+runIndex+"次执行"); } }
7 再次执行下结果如下:
非同步块,顺序执行
非同步块,顺序执行
//执行到此处会发现等待三秒后才执行线程1 的打印,线程1的计数打印完毕后才执行线程2的计数打印。
线程计数, 第 1次执行
线程计数, 第 2次执行
总结:
通过 第5步骤和第7步骤 对比发现,添加同步块的代码只有上一个线程执行完毕后才会允许下一个线程继续执行,
也就是给这个代码块添加了锁,只有线程执行完毕,释放了锁后才允许其他线程获得锁
上述执行代码是我自己试验的结果,总结部分是我自己的理解,不对之处希望大家指正和完善。