线程互斥可以解决多个线程共享一个资源,它有:使用synchronized关键字和显示Lock对象2种方式
使用synchronized关键字
package com.lyj; /** * 线程互斥 * 1. 两个线程共享一个打印方法 * 2. 使用synchronized * @author lyj * */ public class TraditionalSynchronous { public static void main(String[] args) { final Output out = new Output(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } out.print("ilovejava"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } out.print("ilikebeautifulgirl"); } } }).start(); } static class Output { private synchronized void print(String name) { //方法设置为private ,防止其他任务直接访问域 //synchronized (this) { //临界区 for (int i = 0; i < name.length(); i++) { System.out.print(name.charAt(i)); } System.out.println(); //} } } }
使用Lock对象
package com.lyj; /** * 线程互斥 * 1. 两个线程共享一个打印方法 * 2. 使用Lock对象 * @author lyj * */ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockDemo { public static void main(String[] args) { final Output out = new Output(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } out.print("ilovejava"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } out.print("ilikebeautifulgirl"); } } }).start(); } } class Output { // 使用Lock对象 Lock lock = new ReentrantLock(); public void print(String name) { lock.lock(); // finally防止执行for循环中异常退出不能释放Lock对象 try { for (int i = 0; i < name.length(); i++) { System.out.print(name.charAt(i)); } System.out.println(); } finally { lock.unlock(); } } }
显示Lock对象和synchronized比较: Lock对象中try-finaly所需的代码比synchronized关键字要多,这也代表了他的特点之一,如果执行一个事务失败了,synchronized会抛出一个异常,但没有机会去做任何的清理工作,以维护系统使其处于良好状态。有了显示的Lock对象,就可以在finally中做一些清理或其他工作。
总之,因为synchronized关键字代码量小,所以一般用synchronized关键字,除非要解决特殊问题时,用Lock对象。