线程(二)

本文介绍线程的几个方法,如join、Priority、yield、Daemon等。还详细讲解对象锁和类锁,synchronized加在static方法前是类锁,加在非静态方法前是对象锁,二者不同,多线程执行不同锁的方法是异步的,最后提到可通过object方法实现线程分时运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程(二)

线程的几个方法

  • join:相对于main线程来加入 ,会加在main线程前执行
  • Priority:线程的优先级,最大10,最小1,中是5.
  • yield:让位
  • Daemon:守护线程,比如:GC,垃圾回收器

对象锁和类锁

synchronized 加到 static 方法前面是给class 加锁,即类锁;而synchronized 加到非静态方法前面是给对象上锁。
对象锁和类锁是不同的锁,所以多个线程同时执行这2个不同锁的方法时,是异步的。
类锁对该类的所有对象都能起作用,而对象锁不能。
大白话就是:一个线程执行同步的静态方法后,另一个线程就得等第一个线程执行完这个方法后才能继续执行。但是第二个线程可以异步地去执行非静态方法。

对象锁

设置sychronized的两种方式

package com.pro.test6;

public class Syn {
	
	public void m1(){
		//同步块
		synchronized (this) {
			for (int i = 0; i < 5; i++) {
				System.out.println("m1-->" + i);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public synchronized void m2(){
		for (int i = 0; i < 5; i++) {
			System.out.println("m2-->"+i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

测试类调用

package com.pro.test6;

public class Test1 {

	public static void main(String[] args) {
		final Syn syn=new Syn();
		final Syn syn1=new Syn();//不同对象没有互斥关系
		//这里要强调,一个对象一把锁,这个锁会锁住所有标识为synchronized
		//的方法或块。
		//放置在方法和块有什么区别?同步块更优化。
		//徐达
		Thread t1=new Thread(new Runnable() {
			public void run() {
				//任务?
				syn.m1();				
			}
		},"t1");
		//谷忠富
		Thread t2=new Thread(new Runnable() {
			public void run() {
				//任务?
				syn1.m2();
			}
		},"t2");
		t1.start();
		t2.start();
	}

}

结果图
在这里插入图片描述

类锁

  • 记住:静态方法,如果加上了synchronized,所有对象都要排队。
  • 因为类型只有一个,大家来访问,必须要排队。
  • 而非静态方法加上synchronized,因为是对象的方法,那对象上是有锁的。
  • 这个锁不仅仅只锁了一个方法,而是锁了这个对象的所有synchronized方法。
  • 所以说,这个对象没有退出synchronized方法,则其他方法也是被锁的。
  • 问题:synchronized的静态方法和非静态方法,有什么不同?
public class Syn {
	public  void m1(){
		synchronized (Syn.class) {
			for (int i = 0; i < 5; i++) {
				System.out.println("m1-->" + i);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		}
	}
	
	public synchronized static void m2(){
		for (int i = 0; i < 5; i++) {
			System.out.println("m2-->"+i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

测试类

public class Test1 {

	public static void main(String[] args) {
		final Syn syn=new Syn();
		final Syn syn1=new Syn();//不同对象没有互斥关系
		//徐达
		Thread t1=new Thread(new Runnable() {
			public void run() {
				//任务?
				syn.m1();				
			}
		},"t1");
		//谷忠富
		Thread t2=new Thread(new Runnable() {
			public void run() {
				//任务?				
				syn.m2();
			}
		},"t2");
		t1.start();
		t2.start();
	}

}

结果图
在这里插入图片描述

最后可以通过object的两个方法实现线程的分时运行
this.notifyAll();唤醒所有线程
this.wait();等待

public class Data {

	private int num;

	public Data(int num) {
		this.num = num;
	}
	
	public synchronized void printOdd(){
		System.out.println("printOdd,"+Thread.currentThread().getName()+"-->"+(num++));
		this.notifyAll();
		try {
			Thread.sleep(1000);
			this.wait();
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public synchronized void printEven(){
		System.out.println("printEven,"+Thread.currentThread().getName()+"-->"+(num++));
		this.notifyAll();
		try {
			Thread.sleep(1000);
			this.wait();
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}

结果图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值