多线程

多线程的实现方式

extends thread类  implement runnable接口

thread创建线程步骤:

                                1.定义一个类继承Thread。

                                2.重写run方法。

                                3.创建子类对象,就是创建线程对象。

                                4.调用start方法,开启线程并让线程执行,同时还会告诉jvm去调用run方法

runnable创建线程步骤                                  

                                    1、定义类实现Runnable接口。

                                    2、覆盖接口中的run方法。。

                                    3、创建Thread类的对象

                                    4、将Runnable接口的子类对象作为参数传递给Thread类的构造函数。

                                    5、调用Thread类的start方法开启线程。

线程安全:使用同步代码块或同步方法

               同步代码块解决线程安全 实现runnable接口方法
public class Model1 implements Runnable{
	int num=100;
	Object obj=new Object();
	public void run() {
		while (true) {
			synchronized (obj) {
				if(num>0){
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+":"+num);
				}
			}
			
		}
		
	}
	
}

同步方法解决线程安全

同步方法:使用关键字synchronized修饰的方法,一旦被一个线程访问,
则整个方法全部锁住,其他线程则无法访问    继承Thread类

public class Model extends Thread{
	static int num=10;
	Object obj=new Object();
	@Override
	public void run() {
		while(true){
			method1();
		}
	}
	public synchronized void method(){
		if(num>0){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+":"+num);
		}
	}
	//静态同步方法
	public static synchronized void method1(){
		if(num>0){
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println(Thread.currentThread().getName()+":"+num);
	}
}

线程交流之取款

//账户类
public class Account {
	private int account=500;

	public int getAccount() {
		return account;
	}

	public void setAccount(int account) {
		this.account = account;
	}
	//取款方法参数取了多少钱
	public void withdrawal(int quqianshu) {
		account=account-quqianshu;
	}
	public static void main(String[] args) {
		Account ac=new Account();
		System.out.println(ac.getAccount());
	}
	
}
取款
public class Father implements Runnable{
	private Account ac=new Account();
	public void run() {
		for(int i=0;i<6;i++) {
			if(ac.getAccount()<0) {
				System.out.println("账户没钱了");
				break;
			}
			//取款一次100
			makeWithdrawal(100);
			
		}
		 
	}
	//给取款的方法加上同步锁  参数为取款数。
	public synchronized void makeWithdrawal(int amt) {
		if(ac.getAccount()>=amt) {
			System.out.println(Thread.currentThread().getName()+"准备取款");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) { }
				//余额足够取款
				ac.withdrawal(amt);
				System.out.println(Thread.currentThread().getName()+"取款完成,剩余存款为"+ac.getAccount());
				System.out.println("------------------------------------");
		//如果余额不够给出提示
		}else {
			System.out.println("余额不足");
		}
	}
}
//测试
public class Test {
	public static void main(String[] args) {
		Father f=new Father();
		Thread t=new Thread(f);
		Thread t1=new Thread(f);
		t.setName("跳跳");
		t1.setName("跳一跳");
		t.start();
		t1.start();
	}
}

join();//加入

当一个线程需要等待另一个线程运行完毕后在运行就使用join()

例如:有两个线程 线程1和线程2,当线程1调用start(),在调用join()就会让线程1运行完毕才会运行线程2

详细如下:线程1.start();

                 线程1.join();

                 线程2.start();


sleep()和wait()的区别

    1.sleep是thread类里面的方法,用于控制线程

       wait是object的方法,线程间的通讯。与wait配套的方法还有notify和notifyAll.

            notify唤醒一个线程,notifyAll唤醒所有线程让他们一起抢资源

    2.sleep()方法不会释放锁(让线程停止但不会让出资源)

       wait()释放锁(线程停止,让出资源)

    3.wait必须放到同步代码块中


yield();正在运行的线程退出来,然后让大家一起来竞争

线程交互之生产者消费者

product类,包含生产方法消费方法

public class Product {
	//声明仓库的商品有没有
	private boolean flag;
	//声明商品
	private char c;
	
	
	/**
	 * 生产者方法
	 */
	public synchronized void makeProduct(char c) {
		//仓库有商品
		if(flag) {
			System.out.println("仓库有货等待消费者消费");
			try {
				//等待
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//仓库没货生产商品
		this.c=c;
		flag=true;
		//唤醒消费者线程进行消费
		notify();
		System.out.println("生产者生产了商品:"+c+"请消费者消费");
	}
	/*
	 * 消费者方法
	 * 
	 */
	public synchronized char customerProduct() {
		//仓库没有商品
		if(!flag) {
			System.out.println("仓库没有商品,等待生产商品消费");
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("消费者消费了商品"+this.c+",请生产者生产商品");
		flag=false;
		notify();
		return this.c;
		
	}
}

生产者线程

//生产者线程
public class createProduct extends Thread{
	private Product p;
	
	public createProduct(Product p) {
		this.p = p;
	}
	
	
	public void run() {
		for(char c='a';c<'f';c++) {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//调用生产方法
			p.makeProduct(c);
		}
	}
}

消费者线程

//消费者线程
public class CustomerProduct extends Thread{
	private Product p;

	public CustomerProduct(Product p) {
		this.p = p;
	}
	
	
	public void run() {
		char c;
		do {
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//调用消费方法
			c=p.customerProduct();
		}while(c!='f');
	}
}

测试

public class Test {
	public static void main(String[] args) {
		Product p=new Product();
		createProduct cp=new createProduct(p);
		CustomerProduct ct=new CustomerProduct(p);
		cp.start();
		ct.start();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值