首页 > 编程语言 >java 多线程 synchronized

java 多线程 synchronized

时间:2023-04-26 19:33:36浏览次数:34  
标签:java synchronized Thread void t2 t1 new 多线程 public


程序1:

package testsynchronized;

public class Thread1 implements Runnable {

	@Override
	public void run() {
		synchronized (this) {
			for (int i = 0; i < 10; i++) {
				System.out.println(Thread.currentThread().getName()
						+ " synchronized loop " + i);
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Thread1 t1 = new Thread1();
		Thread ta = new Thread(t1, "A");
		Thread tb = new Thread(t1, "B");
		ta.start();
		tb.start();
	}

}



输出:

A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
A synchronized loop 5
A synchronized loop 6
A synchronized loop 7
A synchronized loop 8
A synchronized loop 9
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4
B synchronized loop 5
B synchronized loop 6
B synchronized loop 7
B synchronized loop 8
B synchronized loop 9



因为a先运行,b后运行,所以a先输出,b后输出,而且不会出现a和b并发输出,因为a已经获得了Thread1的对象锁。


程序2:

package testsynchronized;

public class Thread2 {
	public void m1() {
		synchronized (this) {
			int i = 10;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : " + i);
				try {
					Thread.sleep(3000);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	public void m2() {
		int i = 10;
		while (i-- > 0) {
			System.out.println(Thread.currentThread().getName() + " : " + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException ie) {
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Thread2 myt2 = new Thread2();
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				myt2.m1();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				myt2.m2();
			}
		}, "t2");
		t1.start();
		t2.start();
	}

}



输出:

t2 : 9
t1 : 9
t2 : 8
t2 : 7
t2 : 6
t1 : 8
t2 : 5
t2 : 4
t1 : 7
t2 : 3
t2 : 2
t2 : 1
t2 : 0
t1 : 6
t1 : 5
t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0



这个输出不唯一。

可以看出,当一个线程运行同步代码块时,另一个线程可以同时运行非同步代码块。


程序3:

package testsynchronized;

public class Thread3 {
	public void m1() {
		synchronized (this) {
			int i = 10;
			while (i-- > 0) {
				System.out
						.println(Thread.currentThread().getName() + " : " + i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	public void m2() {
		synchronized (this) {
			int i = 10;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : " + i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Thread3 myt3 = new Thread3();
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				myt3.m1();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				myt3.m2();
			}
		}, "t2");
		t1.start();
		t2.start();
	}

}



输出:

t1 : 9
t1 : 8
t1 : 7
t1 : 6
t1 : 5
t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 9
t2 : 8
t2 : 7
t2 : 6
t2 : 5
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0



可以看出,当一个线程运行同步代码块时,另一个线程不能同时运行同步代码块。


程序4:

package testsynchronized;

public class Thread4 {
	public void m1() {
		synchronized (this) {
			int i = 5;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : " + i);
				try {
					Thread.sleep(3000);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	public synchronized void m2() {
		int i = 5;
		while (i-- > 0) {
			System.out.println(Thread.currentThread().getName() + " : " + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException ie) {
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Thread4 myt4 = new Thread4();
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				myt4.m1();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				myt4.m2();
			}
		}, "t2");
		t1.start();
		t2.start();
	}

}



输出:

t1 : 4
t1 : 3
t1 : 2
t1 : 1
t1 : 0
t2 : 4
t2 : 3
t2 : 2
t2 : 1
t2 : 0



可以看出,当一个线程运行同步代码块时,另一个线程就不能同时运行同步方法。


程序5:

package testsynchronized;

public class Thread5 {
	class Inner {
		private void m1() {
			int i = 5;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException ie) {
				}
			}
		}

		private void m2() {
			int i = 5;
			while (i-- > 0) {
				System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i);
				try {
					Thread.sleep(500);
				} catch (InterruptedException ie) {
				}
			}
		}
	}

	private void m1(Inner inner) {
		synchronized (inner) { // 使用对象锁
			inner.m1();
		}
	}

	private void m2(Inner inner) {
		inner.m2();
	}

	public static void main(String[] args) {
		final Thread5 myt5 = new Thread5();
		final Inner inner = myt5.new Inner();
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				myt5.m1(inner);
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				myt5.m2(inner);
			}
		}, "t2");
		t1.start();
		t2.start();
	}
}



输出:

t1 : Inner.m4t1()=4
t2 : Inner.m4t2()=4
t1 : Inner.m4t1()=3
t2 : Inner.m4t2()=3
t1 : Inner.m4t1()=2
t2 : Inner.m4t2()=2
t1 : Inner.m4t1()=1
t2 : Inner.m4t2()=1
t1 : Inner.m4t1()=0
t2 : Inner.m4t2()=0



可以看到,当使用同步代码块时,并非要this,其他对象也可以,而且另一个线程可以同时运行飞同步代码块。


总结


使用synchronized就相当于取得了某个锁,如果是多线程,最多只有一个线程能运行同步方法,但是对于非同步方法,其他线程也能同时运行。


对于下面的代码:

package testsynchronized;

public class Thread6 {
	private boolean a;
	private boolean b;

	public void setA(boolean a) {
		this.a = a;
	}

	public void setB(boolean b) {
		this.b = b;
	}
	
	public synchronized void setSA(boolean a) {
		this.a = a;
	}

	public synchronized void setSB(boolean b) {
		this.b = b;
	}
	
	public void setAB() {
		setSA(true);
		setSB(false);
	}
	
	public synchronized void setSAB() {
		setA(false);
		setB(true);
	}
	
	public void check() {
		System.out.println(a == b);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		final Thread6 myt6 = new Thread6();
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				myt6.setSAB();
				myt6.check();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				myt6.setA(true);
				myt6.setB(true);
			}
		}, "t2");
		t1.start();
		t2.start();
	}

}




是否会输出true。

理论上是有可能输出true的,因为两个线程,分别调用同步方法和非同步方法。为了输出true,可以加些代码:

public static void main(String[] args) {
		final Thread6 myt6 = new Thread6();
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				myt6.setSAB();
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				myt6.check();
			}
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				myt6.setA(true);
				myt6.setB(true);
			}
		}, "t2");
		t1.start();
		t2.start();
	}



这样就输出true了。

标签:java,synchronized,Thread,void,t2,t1,new,多线程,public
From: https://blog.51cto.com/u_1002776/6228671

相关文章

  • java 一些奇怪的笔试题
    例1:packagecom.test;publicclassTest1{ publicvoidtestExit(){ try{ System.exit(0); }finally{ System.out.println("testExit"); } } publicvoidtestReturn(){ try{ return; }finally{ System.out.println("......
  • docker启动rabbitMQ,通过java创建交换机、队列、绑定
    通过docker启动rabbitMQdockerrun-d--namerabbitmq-p5671:5671-p5672:5672-p4369:4369-p25672:25672-p15671:15671-p15672:15672rabbitmq:management  将其修改为自启动:dockerupdaterabbitmq--restart=always  以下为通过java代码进行创建交换机......
  • 【Java设计模式】装饰者设计模式
    目录1.装饰者模式(Wrapper)概念2.装饰者是什么?3.装饰者设计模式-参与者3.1组成3.1Demo1.Component(抽象构件)2.ConcreteComponent(具体构件)3.Decorator(抽象装饰类)4.ConcreteDecorator(具体装饰类)5.Test类:3.2总结4.JDK源码中的装饰者设计模式扩展:开闭原则1.装饰者模式(Wra......
  • VScode 创建Java项目
    1.点击view找到命令行输入java(ctrl+shift+P)src:一般是自己写的源代码的文件lib:外部引用库等其他的内容bin:二进制程序,用以存放未来的编译文件等  ......
  • javascript操作cookie
    functionsetCookie(name,value){varDays=30;varexp=newDate();exp.setTime(exp.getTime()+Days*24*60*60*1000);document.cookie=name+"="+escape(value)+";expires="+exp.toGMTString();......
  • java 多线程的start()和run()的理解
    run()方法中是各个线程要执行的具体内容。所以当一个线程直接调用run()时那么直接开始执行方法体,这是在main线程中的多个线程只能时按照顺序的等待前面的线程结束run()方法的执行。而调用start方法只是线程进入准备阶段(Ready),并没有真正执行,这需要JVM进行分配时间片进行轮转线程执......
  • VScode配置Java环境
    1.安装VScode2.配置Java环境变量3.配置VScodeJava插件参考博文:VSCode配置调试编译java环境,史上最全!!!安装ExtensionPackforJava插件 VScode配置Java:home文件——首选项——设置输入javahome,选择在settings.json中编辑 {"window.zoomLevel":1,//"j......
  • JavaScript怎么判断一个host是否在局域网中?
    在JavaScript中,可以使用WebRTCAPI来判断一个host是否在局域网中。WebRTCAPI提供了一种用于在浏览器中进行实时通信的技术,其中包括了一些用于网络发现的API。下面是一个简单的实现:functioncheckLocalhost(callback){varpc=newRTCPeerConnection({iceServers:[]});pc......
  • 大华面试java 2023.5
    一张表随着业务递增,如何对一个字段进行快速查询。比如对身高字段查询,要求查询是10的倍数的。考虑分库分表,或者提前计算设置标志位加索引OOM的场景有哪些,分别是什么情况下会出现这样的问题项目中的复杂设计开发流程springcloud动态更新class的原理,类加载机制,java中类加载......
  • Java+proj4j实现根据EPSG编码进行坐标系转换
    场景Java+GeoTools实现WKT数据根据EPSG编码进行坐标系转换:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130370754上面使用GeoTools实现坐标系转换。Vue+Openlayers+proj4实现坐标系转换:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/13038879......