通过java代码解决多线程,高并发问题(通过synchronized,Lock对相应代码上锁)

我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了。

今天介绍一下,在java代码层面解决多线程,高并发问题,主要介绍以下3种方式:

以下是未线程安全同步的代码:

class LockTest {
    public static void main(String[] args) {
        final Outputter1 output = new Outputter1();
        //启动新线程1(传承一个多线程环境)
        new Thread() {
            //覆盖run方法
            public void run() {
                //新线程1需要执行的业务代码
                output.output("zhangsan");
            };
        }.start();
        //启动新线程2
        new Thread() {
            public void run() {
                //新线程2需要执行的代码
                output.output("lisi");
            };
        }.start();
    }
}
class Outputter1 {
    public void output(String name) {
         for(int i = 0; i < name.length(); i++) {
             System.out.print(name.charAt(i));
         }
    }
}

结果1:

也可能为:

等等不同结果;

通过结果可以看出:当出现多线程、高并发的情况时运行同一段代码时;会出现不同的结果,从而导致线程安全问题。

要解决以下问题有介绍3中方式:

方式一

      通过synchronized同步方法从而解决高并发问题

class LockTest {
    public static void main(String[] args) {
        final Outputter1 output = new Outputter1();
        //启动新线程1(传承一个多线程环境)
        new Thread() {
            //覆盖run方法
            public void run() {
                //新线程1需要执行的业务代码
                output.output("zhangsan");
            };
        }.start();
        //启动新线程2
        new Thread() {
            public void run() {
                //新线程2需要执行的代码
                output.output("lisi");
            };
        }.start();
    }
}
class Outputter1 {
    //通过synchronized同步方法
    public synchronized void output(String name) {
        for(int i = 0; i < name.length(); i++) {
            System.out.print(name.charAt(i));
        }
    }
}

方式二

       通过synchronized同步代码块从而解决高并发问题

class LockTest {
    public static void main(String[] args) {
        final Outputter1 output = new Outputter1();
        //启动新线程1(传承一个多线程环境)
        new Thread() {
            //覆盖run方法
            public void run() {
                //新线程1需要执行的业务代码
                output.output("zhangsan");
            };
        }.start();
        //启动新线程2
        new Thread() {
            public void run() {
                //新线程2需要执行的代码
                output.output("lisi");
            };
        }.start();
    }
}
class Outputter1 {
    public void output(String name) {
        //同步代码块
        synchronized (this){
            for(int i = 0; i < name.length(); i++) {
                System.out.print(name.charAt(i));
            }
        } 
    }
}

方式三

         通过java.util.concurrent.locks.Lock来对代码进行上锁,从而解决高并发问题

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class LockTest {
    public static void main(String[] args) {
        final Outputter1 output = new Outputter1();
        new Thread() {
            public void run() {
                output.output("zhangsan");
            };
        }.start();
        new Thread() {
            public void run() {
                output.output("lisi");
            };
        }.start();
    }
}
class Outputter1 {
    private Lock lock = new ReentrantLock();// 锁对象
    public void output(String name) {
        // TODO 线程输出方法
        lock.lock();// 得到锁
        try {
            for(int i = 0; i < name.length(); i++) {
                System.out.print(name.charAt(i));
            } 
        } finally {
            lock.unlock();// 释放锁(一定要手动解锁)
        }
    }
}

通过以上3种方式只会得到2种结果:

结果一:

结果二:

通过结果可以看到:

     当一个线程代码执行时当执行完后才执行下一线程代码,从而从代码层面解决了线程安全问题

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页