JAVA学習日記:thread(6)

今日学んだ主な内容:

1.synchronized关键字
2.volatile关键字

同期されたキーワード(同期):

  		synchronized关键字用来声明临界区(java线程中的关键代码块),临界区可以防止多个线程同时使用造成的麻烦。
  		当一个线程调用了临界区,别的线程不能访问除非调用结束。俗称加锁。
  
  		synchronized它拥有两种使用的方式:
  			synchronized方法:
  				加在方法名前是修饰实例方法将锁加在方法上。
				通过修饰静态方法将锁加在类上。
 		
			synchronized块

揮発性キーワード(変更可能):

它只能修饰类的成员变量!(实例、静态的都可)
使用volatile域会导致线程使用主空间(内存)同步他的工作空间。
volatile并不是意味着“原子性”:
 			如果i是volatile,多个线程调用例如i++的操作就不是线程安全操作,我们需要
  			知道i++是多个语句的缩写。

SynchronizedTest01クラス(テストロックインスタンス):

package LessonForThread06;

public class SynchronizedTest01 
{
    
    
	public synchronized void method01()
	{
    
    
		for (int i=0; i<5; i++)
		{
    
    
			try 
			{
    
    
				Thread.sleep(500);
			} catch (InterruptedException e) 
				{
    
    
					e.printStackTrace();
				}
			System.out.println("This is method01 -- "+i);
		}
	}
	
	public synchronized void method02()
	{
    
    
		for (int i=0; i<5; i++)
		{
    
    
			try 
			{
    
    
				Thread.sleep(500);
			} catch (InterruptedException e) 
				{
    
    
					e.printStackTrace();
				}
			System.out.println("This is method02 -- "+i);
		}
	}
	
	public synchronized static void method03()//此时锁的是类!不是实例!
	{
    
    
		for (int i=0; i<5; i++)
		{
    
    
			try 
			{
    
    
				Thread.sleep(500);
			} catch (InterruptedException e) 
				{
    
    
					e.printStackTrace();
				}
			System.out.println("This is static -- "+i);
		}
	}
	
	public static void main(String[] args) 
	{
    
    
		SynchronizedTest01 s1 = new SynchronizedTest01();
		
		
//		Thread t1 = new Thread(s1::method01);//用方法引用
//		Thread t2 = new Thread(()->s1.method01());//用lambda表达式
//		t1.start();
//		t2.start();
//		//此时method01方法有序的被两个线程分别调用,没有杂乱无章。
			
		Thread t3 = new Thread(s1::method01);
		Thread t4 = new Thread(SynchronizedTest01::method03);
		t3.start();
		t4.start();
		
//		Thread t5 = new Thread(SynchronizedTest01::method03);
//		t5.start();
	}
}

SynchronizedTest02クラス(テストロッククラス):

package LessonForThread06;

public class SynchronizedTest02 
{
    
    
	public void method01()
	{
    
    
		synchronized (this)//制作一个同步代码块this表示当前实例!
		{
    
    
			for (int i=0; i<5; i++)
			{
    
    
				try 
				{
    
    
					Thread.sleep(500);
				} catch (InterruptedException e) 
					{
    
    
						e.printStackTrace();
					}
				System.out.println("This is method01 -- "+i);
			}
		}
	}
	
	public void method02()
	{
    
    
		synchronized (this)//锁在字符串上了
		{
    
    
			for (int i=0; i<5; i++)
			{
    
    
				try 
				{
    
    
					Thread.sleep(500);
				} catch (InterruptedException e) 
					{
    
    
						e.printStackTrace();
					}
				System.out.println("This is method02 -- "+i);
			}
		}
	}
	
	public void method03()
	{
    
    
		synchronized ("zlm")//制作一个同步代码块this表示当前实例!
		{
    
    
			for (int i=0; i<5; i++)
			{
    
    
				try 
				{
    
    
					Thread.sleep(500);
				} catch (InterruptedException e) 
					{
    
    
						e.printStackTrace();
					}
				System.out.println("This is method03 -- "+i);
			}
		}
	}
	
	public static void main(String[] args)
	{
    
    
		SynchronizedTest02 s = new SynchronizedTest02();
		//s被锁定
		
		Thread t1 = new Thread(s::method01);
		Thread t2 = new Thread(s::method02);
		Thread t3 = new Thread(s::method03);
		
		t1.start();
		t2.start();
		t3.start();
		//这个同步代码块锁定的是本类的实例。
		//多个线程访问同一个实例的时候,必须得互相排队!
		//而method03此时s没有被锁定,所以会和别的线程交叉出现!!
		//因为此时锁定的不是方法是类的实例。
	}
}
本篇部分文字来源于:
	咕嘟咖啡杨海滨老师 — 《java编程语言高级特性》
	在这里十分感谢老师能够给我带来学习的激情。

2020.10.24程序员节快乐!
可以转载我的学习日记但请注明出处,谢谢。
本文章是本人学习笔记,不进行任何商用!也请别拿去商用!只为记录本人学习历程。
毕	

おすすめ

転載: blog.csdn.net/SIESTA030/article/details/109263132