java中多线程安全性和同步的常用方法
Posted wx6070687864c6e
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中多线程安全性和同步的常用方法相关的知识,希望对你有一定的参考价值。
1、多线程安全性问题,即多线程在什么场景下会出现异常?
多个线程同时调用一个共享的变量(对象),比如当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来,也操作车票。
2、在Java中,我们通过同步机制,来解决线程的安全问题。
3、有几种同步机制?
有3种,同步代码块、同步方法、Lock;
4、同步代码块
代码如下:
synchronized(同步监视器)
//需要被同步的代码
注意:
(1)同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。要求:多个线程必须要共用同一把锁。同步监视器必须唯一,且是一个对象。也就是多个线程共享一个同步监视器对象。否则同步代码块不生效。
(2)包裹的代码是操作共享数据的代码,即为需要被同步的代码。不能多,也不能少,否则就会出错。
(3)共享数据:多个线程共同操作的变量。
(4)在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。
(5)在继承Thread类创建多线程的方式中,慎用this充当同步监视器,考虑使用当前类充当同步监视器。也就是"类名.class",比如“Student.class”。
实例代码1(实现Runnable接口):
class Window1 implements Runnable
private int ticket = 100;
// Object obj = new Object();
// Dog dog = new Dog();
@Override
public void run()
// Object obj = new Object();
while(true)
synchronized (this)//此时的this:唯一的Window1的对象 //方式二:synchronized (dog)
if (ticket > 0)
try
Thread.sleep(100);
catch (InterruptedException e)
e.printStackTrace();
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
else
break;
View Code
实例代码2(继承Thread):
class Window2 extends Thread
private static int ticket = 100;
private static Object obj = new Object();
@Override
public void run()
while(true)
//正确的
// synchronized (obj)
synchronized (Window2.class)//Class clazz = Window2.class,Window2.class只会加载一次
//错误的方式:this代表着t1,t2,t3三个对象
// synchronized (this)
if(ticket > 0)
try
Thread.sleep(100);
catch (InterruptedException e)
e.printStackTrace();
System.out.println(getName() + ":卖票,票号为:" + ticket);
ticket--;
else
break;
View Code
5、同步方法
(1)同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。
(2)非静态的同步方法,同步监视器是:this
静态的同步方法,同步监视器是:当前类本身
实例代码1(实现Runnable接口)
class Window3 implements Runnable
private int ticket = 100;
@Override
public void run()
while (true)
show();
private synchronized void show()//同步监视器:this
//synchronized (this)
if (ticket > 0)
try
Thread.sleep(100);
catch (InterruptedException e)
e.printStackTrace();
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
//
View Code
实例代码2(继承Thread)
class Window4 extends Thread
private static int ticket = 100;
@Override
public void run()
while (true)
show();
private static synchronized void show()//同步监视器:Window4.class
//private synchronized void show() //同步监视器:t1,t2,t3。此种解决方式是错误的
if (ticket > 0)
try
Thread.sleep(100);
catch (InterruptedException e)
e.printStackTrace();
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
View Code
6、单例模式中懒汉模式的线程安全的代码:
lass Bank
private Bank()
private static Bank instance = null;
public static Bank getInstance()
//方式一:效率稍差
// synchronized (Bank.class)
// if(instance == null)
//
// instance = new Bank();
//
// return instance;
//
//方式二:效率更高
if(instance == null)
synchronized (Bank.class)
if(instance == null)
instance = new Bank();
return instance;
View Code
作者:沐雪
文章均系作者原创或翻译,如有错误不妥之处,欢迎各位批评指正。本文版权归作者,如需转载恳请注明。
如果您觉得阅读这篇博客让你有所收获,
为之网-热爱软件编程 http://www.weizhi.cc/
以上是关于java中多线程安全性和同步的常用方法的主要内容,如果未能解决你的问题,请参考以下文章
线程安全问题-synchronized(方法)火车票卖票代码演示