java多线程笔记--synchronized类,对象,方法,代码块

    xiaoxiao2022-07-09  208

    java多线程笔记–synchronized的用法

    文章目录

    java多线程笔记--synchronized的用法1.锁对象, 多线程售票示例2.synchronized类,对象,方法,代码块示例

    * 0)对象锁是用于对象实例方法,或者一个对象实例上的, * 类锁是用于类的静态方法或者一个类的class对象上的(单例模式的双重检测) * 一个线程获得对象锁的同时,也可以获得该类锁,即同时获得两个锁 * 1)synchronized类,和synchronized对象(this) * //synchronized(this)代表锁住同一对象。多个线程竞争锁访问同一对象,对不同对象不竞争 * //synchronized(CountRunnable.class)代表锁住整个CountRunnable类的对象。多个线程对同一类的多个对象也竞争锁访问 * 2)synchronized方法和synchronized代码块 * 同步代码块比同步方法粒度小;一般需要加锁进行同步的时候,肯定是范围越小越好,这样性能更好 * synchronized方法和synchronized代码块(synchronized(this))都是锁当前对象 * 3)当一个线程访问object的一个synchronized(this)同步代码块时, * 另一个线程仍然可以访问该object中的非synchronized(this)同步代码块 * 4)线程访问synchronized内的代码时,会隐式地获取锁,执行完括号中的代码,会隐式地释放锁

    1.锁对象, 多线程售票示例

    package com.ctg.test.thread; /** * @Description: 1)synchronized 类 * 2)synchronized对象(this) * 3)synchronized方法 * 4)synchronized代码块 * @Author: * @Date: 2019/5/22 21:48 */ public class TestSynchronizedTicket { private static int num = 10; public static void main(String[] args) { TicketRunnable ticketRunnable = new TicketRunnable(num); Thread t1 = new Thread(ticketRunnable, "窗口1"); Thread t2 = new Thread(ticketRunnable, "窗口2"); Thread t3 = new Thread(ticketRunnable, "窗口3"); t1.start(); t2.start(); t3.start(); } public static class TicketRunnable implements Runnable { private int ticket; public TicketRunnable(int ticket) { this.ticket = ticket; } @Override public void run() { while (ticket > 0) { //锁对象,多个线程竞争访问同一个对象TicketRunnable ticketRunnable = new TicketRunnable(num) synchronized (this) { if (ticket > 0) { try { ticket--; Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在卖票,还剩:" + ticket); }else{ System.out.println(Thread.currentThread().getName() + "票已卖完" ); } } } } } }

    2.synchronized类,对象,方法,代码块示例

    package com.ctg.test.thread; import java.text.SimpleDateFormat; import java.util.Date; /** * @Description: * @Author: * @Date: 2019/5/22 23:34 */ public class Service { //类锁,锁 静态方法,和f2 f3不竞争 public static synchronized void f0(){ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 System.out.println(df.format(new Date())+";"+Thread.currentThread().getName()+":"+"f0"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } //类锁,锁 类.class,和f2 f3不竞争 public void f1(){ synchronized (Service.class) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 System.out.println(df.format(new Date())+";"+Thread.currentThread().getName()+":"+"f1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } //锁方法,f2 f3竞争(锁的也是当前对象) public synchronized void f2(){ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 System.out.println(df.format(new Date())+";"+Thread.currentThread().getName()+":"+"f2"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } //锁代码块,f2 f3竞争,如果用了同步代码块,那么当退出代码块时就已经释放了对象锁(当前对象this进行加锁) public void f3(){ // synchronized (this) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 System.out.println(df.format(new Date())+";"+Thread.currentThread().getName()+":"+"f3"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } // } //锁普通对象,跟f2 f3不竞争 public void f4(){ String str="test"; synchronized (str) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 System.out.println(df.format(new Date())+";"+Thread.currentThread().getName()+":"+"f4"); } } }

    测试:

    package com.ctg.test.thread; /** * @Description: * 0)对象锁是用于对象实例方法,或者一个对象实例上的, * 类锁是用于类的静态方法或者一个类的class对象上的(单例模式的双重检测) * 一个线程获得对象锁的同时,也可以获得该类锁,即同时获得两个锁 * 1)synchronized类,和synchronized对象(this) * //synchronized(this)代表锁住同一对象。多个线程竞争锁访问同一对象,对不同对象不竞争 * //synchronized(CountRunnable.class)代表锁住整个CountRunnable类的对象。多个线程对同一类的多个对象也竞争锁访问 * 2)synchronized方法和synchronized代码块 * 同步代码块比同步方法粒度小;一般需要加锁进行同步的时候,肯定是范围越小越好,这样性能更好 * synchronized方法和synchronized代码块(synchronized(this))都是锁当前对象 * 3)当一个线程访问object的一个synchronized(this)同步代码块时, * 另一个线程仍然可以访问该object中的非synchronized(this)同步代码块 * 4)线程访问synchronized内的代码时,会隐式地获取锁,执行完括号中的代码,会隐式地释放锁 * @Author: * @Date: 2019/5/22 21:48 */ public class TestSynchronized { /** * 执行结果:f0 f1竞争访问,类锁,和f4不竞争锁 * f2 f3竞争访问对象锁,和f4不竞争锁 * @param args */ public static void main(String[] args) { Service service=new Service(); Thread t0 = new Thread(new Runnable() { @Override public void run() { Service.f0(); } },"线程0"); Thread t1 = new Thread(new Runnable() { @Override public void run() { service.f1(); } },"线程1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { service.f2(); } },"线程2"); Thread t3 = new Thread(new Runnable() { @Override public void run() { service.f3(); } },"线程3"); Thread t4 = new Thread(new Runnable() { @Override public void run() { service.f4(); } },"线程4"); t0.start(); t1.start(); // t2.start(); // t3.start(); // t4.start(); } }
    最新回复(0)