进程:程序的一次动态加载过程,包括了代码加载,编译,执行,结束的一个完整过程
线程:线程是比进程更小的单位,行为很像进程,一个进程在执行过程中可以产生多个线程
Java多线程机制

多线程序机制:每个java程序都有一个主线程,当jvm加载代码,发现main方法,此时就会启动主线程,在mian方法执行过程中再创建的线程就是其他线程。

线程的四种状态:
新建状态:Thread类被创建
运行状态:执行run()方法
中断状态:

  • 1.资源从当前线程被切换给了其他线程
  • 2.调用sleep()方法
  • 3.wait()方法
  • 4 .线程执行某个操作期间进入了阻塞状态

死亡状态:1.正常运行完全部工作 2.被强制中断

状态图:
Java多线程机制
java线程的优先级在常数1-10之间,默认为5级

创建线程的三种方法:

1.线程任务类,接口Runnable

public class ThreadB implements Runnable{
	@Override
	public void run() {
		for(int i=0;i<10;i++) {
			System.out.println(i+"B线程");
		}
	}
}

启动线程时,需要通过Thread 对象进行启动

public class ThreadTestB {

	public static void main(String[] args) {
		//1.创建线程任务
		ThreadB tb=new ThreadB();
		//2.通过线程任务,创建线程对象
		Thread t=new Thread(tb);
		t.start();
		for(int i=0;i<10;i++) {
			System.out.println(i+"Main线程");
		}
	}

}

2.继承Thread的线程类

public class ThreadTestA {

	public static void main(String[] args) {
		//1.创建线程对象
		ThreadA ta=new ThreadA();
		ta.start();
		for(int i=0;i<10;i++) {
			System.out.println(i+"Main线程");
		}
	}

}

启动线程时,直接 new 线程对象.start()方法

public class ThreadA extends Thread{
	@Override
	public void run() {
		for(int i=0;i<10;i++) {
			System.out.println(i+"A线程");
		}
	}
}

线程同步(synchronized)

问题:当两个或多个线程同时访问同一变量时,并且对该变量会进行修改,那么就可能会出现混乱
线程同步方法:使用 synchronized 修饰来方法
线程同步机制:当一个线程A使用synchronized方法时,其他线程想用synchronized方法时就必须等待,直到线程A使用完synchronized方法。

例子:会计和出纳共同拥有一个账本,他们都可以使用saveOrTake方法对账本进行访问。如果会计正在使用saveOrTake存入钱时,出纳被禁止使用,反之如此。

package com.money;
//线程同步(synchronized):
public class Test {

	public static void main(String[] args) {
		Bank bank = new Bank();
		bank.setMoney(300);
		Thread accountant = new Thread(bank); //声明线程变量会计
		Thread cashier = new Thread(bank); //声明线程变量出纳
		accountant.setName("accountant");
		cashier.setName("cashier");
		accountant.start();
		cashier.start();
	}

}
package com.money;

public class Bank implements Runnable {
	int money = 200;
	public void setMoney(int n) {
		money = n;
	}
	
	public void run() {
		if(Thread.currentThread().getName().equals("accountant")) {
			saveOrTake(300);
		}else if(Thread.currentThread().getName().equals("cashier")) {
			saveOrTake(150);
		}
	}

	//存取方法  (如果将synchronized取掉,线程就不会有等待,结果将会不一样)
	public synchronized void saveOrTake(int amount) {
		if(Thread.currentThread().getName().equals("accountant")) {
			for(int i=1;i<=3;i++) {
				money=money+amount/3;   //每次存入100,暂停一下
				System.out.println(Thread.currentThread().getName()+
						"存入"+amount/3+"元,账上有"+money+"元");
			}
			try {
				Thread.sleep(1000);    //此时出纳无法使用saveOrTake方法
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		else if(Thread.currentThread().getName().equals("cashier")) {
			for(int i=1;i<=3;i++) {
				money=money-amount/3;   //每次取出50,暂停一下
				System.out.println(Thread.currentThread().getName()+
						"取出"+amount/3+"元,账上有"+money+"元");
			}
			try {
				Thread.sleep(1000);   //此时会计无法使用saveOrTake方法
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}
}

Java多线程机制


协调同步的线程(wait)

问题:当一个线程使用同步方法后,其他线程就必须等待,直到当前线程使用完该方法。同步方法特殊情况。
方法:当一个线程中在使用的同步方法时,需要用到其中的某个变量,而此变量又需要其他线程修改后才符合此线程的需要,此时就需要用wait()方法。
wait()方法:中断线程的执行,使当前线程等待,允许其他线程使用这个同步方法。使用完后通过线程结束等待:notify(),notifyall()

例子:A和B买电影票,电影票5元一张,售票员只有两张5元的钱,A有20元排第一位,B有5元排第二位。因此A必须等待B先买票。

package com.ticket;

public class Test {
	public static void main(String[] args) {
		Ticket ticket = new Ticket();
		Thread A = new Thread(ticket);
		Thread B = new Thread(ticket);
		A.setName("A");
		B.setName("B");
		A.start();
		B.start();
	}
}
package com.ticket;

public class Ticket implements Runnable {
	int five=2;
	int twenty=0;
	@Override
	public void run() {
		if(Thread.currentThread().getName().equals("A")) {
			saleTicket(20);
		}else if(Thread.currentThread().getName().equals("B")) {
			saleTicket(5);
		}
	}
	
	public synchronized void saleTicket(int money) {
		if(money==5) {
			five=five+1;
			System.out.println(Thread.currentThread().getName()+"拿到入场票");
		}else if(money==20) {
			while(five<3) {  //如果5元少于3张则需要等待
				try {
					System.out.println(Thread.currentThread().getName()+"等待买票");
					wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			five=five-3;
			twenty=twenty+1;
			System.out.println(Thread.currentThread().getName()+"拿到入场票,收到15元找零");
		}
		notifyAll();
	}
}

Java多线程机制

相关文章: