java同步代码线程 java中线程同步的几种方法( 二 )


下面以一个简单的实例来进行对比分析 实例要完成的工作非常简单 就是创建 个线程 每个线程都打印从 到 这 个数字 java同步代码线程我们希望线程之间不会出现交叉乱序打印 而是顺序地打印
先来看第一段代码 这里java同步代码线程我们在run()方法中加入了synchronized关键字 希望能对run方法进行互斥访问 但结果并不如我们希望那样 这是因为这里synchronized锁住的是this对象 即当前运行线程对象本身 代码中创建了 个线程 而每个线程都持有this对象的对象锁 这不能实现线程的同步
代码package vista;class MyThread implements java lang Runnable {private int threadId;
public MyThread(int id) {this threadId = id;}
@Overridepublic synchronized void run() {for (int i = ; i; ++i) {System out println( Thread ID: + this threadId + : + i);}}}
public class ThreadDemo {/*** @param args* @throws InterruptedException*/public static void main(String[] args) throws InterruptedException {for (int i = ; i; ++i) {new Thread(new MyThread(i)) start();Thread sleep( );}}}
从上述代码段可以得知 要想实现线程的同步 则这些线程必须去竞争一个唯一的共享的对象锁
基于这种思想 我们将第一段代码修改如下所示 在创建启动线程之前 先创建一个线程之间竞争使用的Object对象 然后将这个Object对象的引用传递给每一个线程对象的lock成员变量 这样一来 每个线程的lock成员都指向同一个Object对象 我们在run方法中 对lock对象使用synchronzied块进行局部封锁 这样就可以让线程去竞争这个唯一的共享的对象锁 从而实现同步
代码package vista;
class MyThread implements java lang Runnable {private int threadId;private Object lock;
public MyThread(int id Object obj) {this threadId = id;this lock = obj;}
@Overridepublic void run() {synchronized (lock) {for (int i = ; i; ++i) {System out println( Thread ID: + this threadId + : + i);}}}}
public class ThreadDemo {/*** @param args* @throws InterruptedException*/public static void main(String[] args) throws InterruptedException {Object obj = new Object();for (int i = ; i; ++i) {new Thread(new MyThread(i obj)) start();Thread sleep( );}}}
从第二段代码可知 同步的关键是多个线程对象竞争同一个共享资源即可 上面的代码中是通过外部创建共享资源 然后传递到线程中来实现 我们也可以利用类成员变量被所有类的实例所共享这一特性 因此可以将lock用静态成员对象来实现 代码如下所示
代码package vista;
class MyThread implements java lang Runnable {private int threadId;private static Object lock = new Object();
public MyThread(int id) {this threadId = id;}
@Overridepublic void run() {synchronized (lock) {for (int i = ; i; ++i) {System out println( Thread ID: + this threadId + : + i);}}}}
public class ThreadDemo {/*** @param args* @throws InterruptedException*/public static void main(String[] args) throws InterruptedException {for (int i = ; i; ++i) {new Thread(new MyThread(i)) start();Thread sleep( );}}}
再来看第一段代码 实例方法中加入sychronized关键字封锁的是this对象本身 而在静态方法中加入sychronized关键字封锁的就是类本身 静态方法是所有类实例对象所共享的 因此线程对象在访问此静态方法时是互斥访问的 从而可以实现线程的同步 代码如下所示
代码package vista;
class MyThread implements java lang Runnable {private int threadId;
public MyThread(int id) {this threadId = id;}
@Overridepublic void run() {taskHandler(this threadId);}
private static synchronized void taskHandler(int threadId) {for (int i = ; i; ++i) {System out println( Thread ID: + threadId + : + i);}}}
lishixinzhi/Article/program/Java/gj/201311/27441
【java同步代码线程 java中线程同步的几种方法】