Java多线程冲突解决——同步锁

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程冲突解决——同步锁相关的知识,希望对你有一定的参考价值。

 
 转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827547.html 
 
解决并行冲突最有效的方法就是加同步锁,主要有以下几种方法:
 
1:动态方法同步锁:锁当前对象。即调用该方法的类对象优先执行完毕才到下一个任务。
public synchronized void 方法()
{
}
实例代码:

import java.lang.Thread.State;

import org.omg.CORBA.PUBLIC_MEMBER;

public class ThreadTest {
public static void main(String[] args) throws Exception{
MyRunnable m1=new MyRunnable();
Thread t1=new Thread(m1);
Thread t2=new Thread(m1);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(MyRunnable.num);
}
}
class MyRunnable implements Runnable
{
public static int num=0;
public synchronized void add()
{
for(int i=0;i<100;++i)
{
num++;
}
}
@Override
public void run() {
add();
}
}

 结果:200
2:静态方法同步锁:锁当前类。即:该类的所有类对象优先执行。凡是该类的对象且已经调用运行的,则这些类对象都是平级的,交替运行。而这些对象对于其他类的对象则是优先的,先执行。
public static synchronized void 方法()
{
}
实例:

import java.lang.Thread.State;

import org.omg.CORBA.PUBLIC_MEMBER;

public class ThreadTest {
public static void main(String[] args) throws Exception{
MyRunnable m1=new MyRunnable();
MyRunnable m2=new MyRunnable();
Thread t1=new Thread(m1);
Thread t2=new Thread(m2);
t1.start();
t2.start();

t1.join();
t2.join();
System.out.println(MyRunnable.num);
}
}
class MyRunnable implements Runnable
{
public static int num=0;
public synchronized static void add()
{
for(int i=0;i<100;++i)
{
num++;
}
}
@Override
public void run() {
add();
}
}

结果:200

 
 
3:代码同步锁:设置一个对象(绣球),用来标识谁来执行被锁的代码块。谁拿到这个对象(抢绣球),谁就执行。并且,在执行过程中绣球可能被抢走,这时候就是抢走了绣球那个线程类执行这段代码。
runnable()
{
  public Object lock=new Object();
  public void 方法()
  {
    synchronized(lock){代码块};
   }
}
若两个thread类对象用同一个runnable参数,则lock对象公用,两个线程谁拿到lock对象谁运行被锁代码块,最终结果是确定的。

import java.lang.Thread.State;

import org.omg.CORBA.PUBLIC_MEMBER;

public class ThreadTest {
public static void main(String[] args) throws Exception{
MyRunnable m1=new MyRunnable();

Thread t1=new Thread(m1);
Thread t2=new Thread(m1);
t1.start();
t2.start();

t1.join();
t2.join();
System.out.println(MyRunnable.num);
}
}
class MyRunnable implements Runnable
{
public static int num=0;
public Object lock=new Object();
public void add()
{
synchronized (lock) {
for(int i=0;i<100000;++i)
{
num++;
}
}
}
@Override
public void run() {
add();
}
}

结果:200000

 
 
若两个thread类对象不用同一个runnable对象参数,则两个线程分别对应一个lock代码块,两线程独立运行lock代码块,但交替使用CPU,会导致结果飘忽不定。

import java.lang.Thread.State;

import org.omg.CORBA.PUBLIC_MEMBER;

public class ThreadTest {
public static void main(String[] args) throws Exception{
MyRunnable m1=new MyRunnable();
MyRunnable m2=new MyRunnable();
Thread t1=new Thread(m1);
Thread t2=new Thread(m2);
t1.start();
t2.start();

t1.join();
t2.join();
System.out.println(MyRunnable.num);
}
}
class MyRunnable implements Runnable
{
public static int num=0;
public Object lock=new Object();
public void add()
{
synchronized (lock) {
for(int i=0;i<100000;++i)
{
num++;
}
}
}
@Override
public void run() {
add();
}
}

多调试几次:结果是随机的,循环次数越大结果越随机。比如,上面for循环中如果是i<100,那么可能结果总是200,这看起来是对的,没错。原因是循环次数太少,两线程对结果影响不大。当把数字调大,如100000时,结果就很随机了,有可能是103453,112378。。。。。。。

 
 
 
 
 

以上是关于Java多线程冲突解决——同步锁的主要内容,如果未能解决你的问题,请参考以下文章

多线程同步锁的实现方式

深入Java多线程锁策略

java多线程 -- 同步鎖

Java多线程——线程同步

Java_多线程实现同步

java 多线程 day03 线程同步