讨论:深入理解“一个对象一把锁”
Java多线程中,临界资源以对象的形式存在,当多个线程访问同一个临界资源时首先要获取该对象的锁,而且一个对象只有一把锁,想必这个原理大家都知道。先看一个例子:现在要从1顺次数到90,开启三个线程,每个线程数三十个,不能重复,不能乱序。题目很简单,只要做好同步就行了。
首先是代码一:
public class Demo{ public static void main(String args[]) { MyThread mt1 = new MyThread(); MyThread mt2 = new MyThread(); MyThread mt3 = new MyThread(); new Thread(mt1, "线程1").start(); new Thread(mt2, "线程2").start(); new Thread(mt3, "线程2").start(); }}class MyThread implements Runnable{ private static Integer id = 0; public void run() { for(int i = 0; i < 30; i ++) { synchronized(id) { id++; System.out.println(Thread.currentThread().getName() + " id = " + id); } } }}
public class Demo5{ public static void main(String args[]) { MyThread5 mt = new MyThread5(); new Thread(mt, "线程1").start(); new Thread(mt, "线程2").start(); }}class MyThread5 implements Runnable{ private static Integer id = 0; public void run() { synchronized(id) { id++; String name = Thread.currentThread().getName(); if(name.equals("线程1")) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(name + " id = " + id); } }}
public class Demo5{ public static void main(String args[]) { MyThread5 mt = new MyThread5(); new Thread(mt, "线程1").start(); new Thread(mt, "线程2").start(); }}class MyThread5 implements Runnable{ private static StringBuilder id = new StringBuilder("0"); public void run() { synchronized(id) { int t = Integer.parseInt(id.toString()); t++; id.delete(0, id.length()); id.append(t); String name = Thread.currentThread().getName(); if(name.equals("线程1")) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(name + " id = " + id); } }}
public class Demo{ public static void main(String args[]) { MyThread mt1 = new MyThread(); new Thread(mt1, "线程1").start(); new Thread(mt1, "线程2").start(); new Thread(mt1, "线程3").start(); } }class MyThread implements Runnable{ private static Integer id = 0; private static Integer d = 0; public void run() { for(int i = 0; i < 30; i ++) { synchronized(id) { d++; System.out.println(Thread.currentThread().getName() + " d = " + d); } } }}