Java传统线程互斥技术

Java多线程基础(三)Java传统线程互斥技术

java的线程互斥主要通过synchronized关键字实现。下面的示例代码展示了几种使用synchronized关键字的基本用法。

package com.ming.thread;

public class TestThread {
    public static void main(String[] args) {
        TestThread test=new TestThread();
        test.init();
        //test.init1();
    }
    private void init(){

        new Thread(new Runnable() {

            @Override
            public void run() {
                 while(true) {
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //num.sayHello("123456789");
                        //num.sayHello1("123456789");
                        //num.sayHello3("123456789");
                        //num.sayHello4("123456789");
                        final Num num=new Num();
                        num.sayHello5("123456789");
                    }
            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                 while(true) {
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //num.sayHello("chenhuaming");
                        //num.sayHello1("chenhuaming");
                        //num.sayHello3("chenhuaming");
                        //num.sayHello4("chenhuaming");
                        final Num num=new Num();
                        num.sayHello5("chenhuaming");
                    }
            }
        }).start();
    }

    private void init1(){
        new Thread(new Runnable() {

            @Override
            public void run() {
                 while(true) {
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //Num.sayHello11("123456789");
                        Num.sayHello12("123456789");
                    }
            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                 while(true) {
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //Num.sayHello11("chenhuaming");
                        Num.sayHello12("chenhuaming");
                    }
            }
        }).start();
    }

    static class Num{
        String _lock ="";
        final static String final_lock="";

        //线程不安全
        /*
         * 多个操作者(线程)必须操作同一个对象
         */
        public void sayHello(String name){
            int len = name.length();
            for(int i=0; i<len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }
        //线程不安全
        /*
         * 原因:
         * 锁对象不互斥,锁对象应该使用共享对象
         * 解决方案如:sayHello2 sayHello3 sayHello4
         */
        public void sayHello1(String name){
            synchronized (name) {
                int len = name.length();
                for(int i=0; i<len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
        }
        //线程安全
        /*
         * 方法1:
         * 
         * 使用共享类对象作为对象锁
         */
        public void sayHello2(String name){
            synchronized (this) {
                int len = name.length();
                for(int i=0; i<len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
        }
        //线程安全
        /*方案2:
         * 
         * 以自定义对象作为锁对象,
         * 与使用_lock加锁的代码块互斥
         */
        public void sayHello3(String name){
            synchronized (_lock ) {
                int len = name.length();
                for(int i=0; i<len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
        }
        //线程安全
        /*
         * 同步方法
         */
        public synchronized void sayHello4(String name){
            int len = name.length();
            for(int i=0; i<len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }

        public void sayHello5(String name){
            synchronized (Num.class) {
                int len = name.length();
                for(int i=0; i<len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
        }

        /**************静态方法************/
        //线程不安全
        public static void sayHello11(String name){
            int len = name.length();
            for(int i=0; i<len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }
        //线程安全
        public static void sayHello12(String name){
            synchronized (final_lock) {
                int len = name.length();
                for(int i=0; i<len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }

        }
        //线程安全
        public static void sayHello13(String name){
            synchronized (Num.class) {
                int len = name.length();
                for(int i=0; i<len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
        }
        //线程安全
        public synchronized static void sayHello14(String name){
            int len = name.length();
            for(int i=0; i<len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
        }
    }

}

上面的代码中展示了三种基本的线程互斥实现。下面详述三种方法的实现特点和适用情况。

以this作为锁对象
实现方式
synchronized(this){…}
synchronized实例方法
适用情况
适用于使用类的同一个实例(对象)作为锁对象。下面情况不适用:
若上述代码中第26行和第39行,改为
new Printer().output(“<相应字符串>”);
则无法使用本方法实现线程互斥,而须采用第2种方法。

以Outputer.class作为锁对象
Outputer类的字节码对象由jvm自动加载。
实现方式
synchronized(Outputer.class){…}
static synchronized方法
适用情况
适用于整个类的所有对象都需要互斥访问的情况。

以自定义的对象作为所对象
实现方式
synchronized(<自定义锁对象>){…}
适用情况
同一个类中代码块或者方法的互斥,一般可以用第1种和第2种方法替换。当出现需要在多个类(或者多个类的实例)之间进行互斥控制时,可能需要采用本方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值