java 多线程(1)

1.线程初始化new Thread(Runnable target,String name);一个实现了Runnable接口的类,注意extends Thread也自动实现了Runnable接口,name可有可无。

2.synchronized是对类的当前实例进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块,注意这里是“类的当前实例”, 类的两个不同实例就没有这种约束了。那么static synchronized就是类的class锁,并不能锁住对象锁,只能锁同样为class的锁

3.synchronized锁代码块可以加快效率,因为没锁的地方可以异步运行,synchronized(this)等同于在方法上加synchronized,除了this,还可以锁任意对象,一般是静态变量及方法参数,通过锁不同的对象,使得不同对象锁之间可以异步运行,大大提高效率

4.synchronized可重入锁,异常释放所有锁

5.volatile的作用是强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值,但volatile最致命的缺点是不支持原子性,只保证可见性,即多线程读取共享变量时可以获得最新值使用,但并不是线程安全的,synchronized也可以做到可见性,但synchronized效率低于volatile

6.java为每个object对象都实现了wait()和notify()方法,它们必须用在被synchronized同步的Object的临界区内,否则报错,wait()方法可以使调用改方法的线程释放共享资源的锁,然后从运行状态推出,进入等待队列,直到被再次唤醒,notify()方法可以随时唤醒等待队列中等待同一资源的一个线程,但并不释放共享资源的锁。生产者消费者:

import java.util.ArrayList;
import java.util.List;

class Product{
	private List<String> li=new ArrayList<>();
	synchronized void add() {
		while (li.size()>0) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		li.add(""+Math.random());
		System.err.println(Thread.currentThread().getName()+" 增加了商品: "+li.get(li.size()-1));
		this.notifyAll();
	}
	synchronized void consume() {
		while (li.size()==0) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.err.println(Thread.currentThread().getName()+" 消费了商品: "+li.get(li.size()-1));
		li.remove(li.size()-1);
		this.notifyAll();
	}
}
class P extends Thread{
	private Product product;
	P(Product product){
		this.product=product;
	}
	@Override
	public void run(){
		while (true) {
			product.add();
		}
	}
}
class C extends Thread{
	private Product product;
	C(Product product){
		this.product=product;
	}
	@Override
	public void run(){
		while (true) {
			product.consume();
		}
	}
}
public class Test1 {
	public static void main(String[] args) {
		Product product=new Product();
		Thread p1=new P(product);
		p1.setName("p1");
		Thread p2=new P(product);
		p2.setName("p2");
		Thread c1=new C(product);
		c1.setName("c1");
		Thread c2=new C(product);
		c2.setName("c2");
		p1.start();
		p2.start();
		c1.start();
		c2.start();
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_43245707/article/details/85217758