多线程的实现方式
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();
}
}