现在的位置: 首页 > 综合 > 正文

线程学习之线程互斥

2018年05月26日 ⁄ 综合 ⁄ 共 1852字 ⁄ 字号 评论关闭

线程互斥可以解决多个线程共享一个资源,它有:使用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对象。

抱歉!评论已关闭.