Java_基础—多线程(同步代码块和同步方法)
一、什么情况下需要同步?
- 当多线程并发, 有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作. 这时就需要同步.
- 如果两段代码是同步的, 那么同一时间只能执行一段, 在一段代码没执行结束之前, 不会执行另外一段代码.
二、同步代码块
- 使用synchronized关键字加上一个锁对象来定义一段代码, 这就叫同步代码块
- 多个同步代码块如果使用相同的锁对象, 那么他们就是同步的
package com.soar.syn;
public class Demo1_Synchronized {
/*
* 同步代码块
*/
public static void main(String[] args) {
final Printer p = new Printer(); //匿名内部类使用局部变量必须使用final修饰
new Thread(){
public void run(){
while(true){
p.print1();
}
}
}.start();
new Thread(){
public void run(){
while(true){
p.print2();
}
}
}.start();
}
}
class Printer {
Demo d = new Demo();
public void print1(){
synchronized(d){ //同步代码块,锁机制,锁对象可以是任意的
System.out.println("S");
System.out.println("o");
System.out.println("a");
System.out.println("r");
System.out.println();
}
}
public void print2(){
//synchronized(new Demo()){ //锁对象不能用匿名对象,因为匿名对象不是同一个对象
synchronized(d){
System.out.println("S");
System.out.println("i");
System.out.println("r");
System.out.println();
}
}
}
class Demo{
}
三、同步方法的使用
使用synchronized关键字修饰一个方法, 该方法中所有的代码都是同步的,锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,不能用匿名对象
- 非静态的同步方法的锁是this
- 静态的同步方法的琐是字节码对象(类名.class)
package com.soar.syn;
public class Demo2_Synchronized {
/*
* 同步方法中的代码块
*/
public static void main(String[] args) {
final Printer p = new Printer(); //匿名内部类使用局部变量必须使用final修饰
new Thread(){
public void run(){
while(true){
p.print1();
}
}
}.start();
new Thread(){
public void run(){
while(true){
p.print2();
}
}
}.start();
}
}
/*
//非静态的同步方法的锁对象是什么?
//非静态的同步方法的锁对象是this
class Printer {
public synchronized void print1(){ //同步方法只需要在方法上加synchronized关键字即可
System.out.println("S");
System.out.println("o");
System.out.println("a");
System.out.println("r");
System.out.println();
}
public void print2(){
synchronized(this){
System.out.println("S");
System.out.println("i");
System.out.println("r");
System.out.println();
}
}
}*/
//静态的同步方法的锁对象是什么呢?
//是该类的字节码对象
class Printer {
public static synchronized void print1(){ //同步方法只需要在方法上加synchronized关键字即可
System.out.println("S");
System.out.println("o");
System.out.println("a");
System.out.println("r");
System.out.println();
}
public static void print2(){
synchronized(Printer.class){
System.out.println("S");
System.out.println("i");
System.out.println("r");
System.out.println();
}
}
}