多线程同步有哪些方法?
Posted 本站大佬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程同步有哪些方法?相关的知识,希望对你有一定的参考价值。
不同步代码如下:
package com;
public class A2
public static void main(String[] args) throws InterruptedException
final Blank blank = new Blank();
Thread thread1 = new Thread(new Runnable()
@Override
public void run()
try
blank.get(100);
catch (InterruptedException e)
e.printStackTrace();
);
Thread thread2 = new Thread(new Runnable()
@Override
public void run()
try
blank.get(100);
catch (InterruptedException e)
e.printStackTrace();
);
thread1.start();
thread2.start();
Thread.sleep(2000);
System.out.println(blank.look());
class Blank
// 账户余额
private int money=100;
// 存钱
public void put(int number)
money = money + number;
System.out.println("存钱当前余额"+look());
// 取钱
public void get(int number) throws InterruptedException
if (money < number)
System.out.println("余额不足");
return;
Thread.sleep(1000);
money = money - number;
System.out.println("取钱当前余额"+look());
public int look()
return money;
1、使用synchronized关键字。
package com;
public class A3
public static void main(String[] args) throws InterruptedException
final Blank3 blank = new Blank3();
Thread thread1 = new Thread(new Runnable()
@Override
public void run()
try
blank.get(100);
catch (InterruptedException e)
e.printStackTrace();
);
Thread thread2 = new Thread(new Runnable()
@Override
public void run()
try
blank.get(100);
catch (InterruptedException e)
e.printStackTrace();
);
thread1.start();
thread2.start();
Thread.sleep(2000);
System.out.println(blank.look());
class Blank3
// 账户余额
private int money=100;
// 存钱
public synchronized void put(int number)
money = money + number;
System.out.println("存钱当前余额"+look());
// 取钱
public synchronized void get(int number) throws InterruptedException
if (money < number)
System.out.println("余额不足");
return;
Thread.sleep(1000);
money = money - number;
System.out.println("取钱"+number+"当前余额"+look());
public synchronized int look()
return money;
2、wait和notify
package com;
public class A4
public static void main(String[] args) throws InterruptedException
GetAndSet getAndSet = new GetAndSet();
GetThread getThread1 = new GetThread(getAndSet);
GetThread getThread2 = new GetThread(getAndSet);
GetThread getThread3 = new GetThread(getAndSet);
GetThread getThread4 = new GetThread(getAndSet);
SetThread setThread1 = new SetThread(getAndSet);
getThread1.start();
getThread2.start();
getThread3.start();
getThread4.start();
Thread.sleep(1000);
setThread1.start();
class GetThread extends Thread
private GetAndSet getAndSet;
public GetThread(GetAndSet getAndSet)
this.getAndSet = getAndSet;
@Override
public void run()
try
getAndSet.Get();
catch (InterruptedException e)
e.printStackTrace();
class SetThread extends Thread
private GetAndSet getAndSet;
public SetThread(GetAndSet getAndSet)
this.getAndSet = getAndSet;
@Override
public void run()
try
getAndSet.Set();
catch (InterruptedException e)
e.printStackTrace();
class GetAndSet
private int singal;
public synchronized void Get() throws InterruptedException
System.out.println("进入Get");
if (singal != 1)
System.out.println(Thread.currentThread().getName());
wait();
System.out.println("结束Get");
public synchronized void Set() throws InterruptedException
System.out.println("进入Set");
singal = 1;
Thread.sleep(4000);
notify();
notifyAll();
System.out.println("结束Set");
3、使用特殊域变量volatile实现线程同步。
3.使用特殊域变量(volatile)实现线程同步
- a.volatile关键字为域变量的访问提供了一种免锁机制,
- b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
- c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
- d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量
————————————————
版权声明:本文为CSDN博主「北漂的橙子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/w893433055/article/details/85394588
package com;
public class A5
public static void main(String[] args)
final Blank5 blank5 = new Blank5();
new Thread(new Runnable()
@Override
public void run()
blank5.setMoney(80);
).start();
new Thread(new Runnable()
@Override
public void run()
blank5.setMoney(80);
).start();
new Thread(new Runnable()
@Override
public void run()
blank5.setMoney(80);
).start();
class Blank5
private volatile int money = 100;
public void setMoney(int number)
if (money >= number)
money = money - number;
System.out.println("取出了"+number+"剩余"+money);
System.out.println("余额不足");
4、使用可重入锁实现线程同步。
package com;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class A6
public static void main(String[] args)
Blank6 blank6 = new Blank6();
new Thread(new Runnable()
@Override
public void run()
blank6.setMoney(80);
).start();
new Thread(new Runnable()
@Override
public void run()
blank6.setMoney(80);
).start();
new Thread(new Runnable()
@Override
public void run()
blank6.setMoney(80);
).start();
class Blank6
private int money = 100;
private Lock lock = new ReentrantLock();
public void setMoney(int number)
lock.lock();
try
if (money >= number)
money = money - number;
System.out.println("取出了"+number+"剩余"+money);
else
System.out.println("余额不足");
return;
finally
lock.unlock();
5、使用局部变量实现线程同步。
五、使用ThreadLocal管理局部变量实现线程同步
ThreadLocal管理变量,则每一个使用该变量的线程都获得一个该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的副本,而不会对其他线程产生影响。
ThreadLocal类常用的方法:
1、get():返回该线程局部变量的当前线程副本中的值。
2、initialValue():返回此线程局部变量的当前线程的”初始值“。
3、remove():移除此线程局部变量当前线程的值。
4、set(T value):将此线程局部便利啊ing的当前线程副本中的值设置为指定值value。
https://blog.csdn.net/zhaojw_420/article/details/67823750
http://www.javashuo.com/article/p-sxmqgikl-hx.html
package com;
public class A7
public static void main(String[] args) throws InterruptedException
Blank7 blank7 = new Blank7();
new Thread(new Runnable()
@Override
public void run()
blank7.setMoney(80);
).start();
Thread.sleep(1000);
blank7.getMoney();
new Thread(new Runnable()
@Override
public void run()
blank7.setMoney(80);
).start();
Thread.sleep(1000);
blank7.getMoney();
new Thread(new Runnable()
@Override
public void run()
blank7.setMoney(80);
).start();
class Blank7
private static ThreadLocal<Integer> money = new ThreadLocal<Integer>()
@Override
protected Integer initialValue()
return 100;
;
public void getMoney()
System.out.println(money.get());
public void setMoney(int number)
if (money.get() - number >= 0)
money.set(money.get()-number);
System.out.println("取出了"+number+"剩余"+money.get());
else
System.out.println("余额不足");
return;
6、使用阻塞队列实现线程同步。
7、使用原子变量实现线程同步。
https://blog.csdn.net/kehyuanyu/article/details/24797129
以上是关于多线程同步有哪些方法?的主要内容,如果未能解决你的问题,请参考以下文章