Chapter seventeen 嵌入式Java浅谈(1)
17.1 嵌入式Java
17.1.1Java多线程
- 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
- 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,最典型的场景就是我们用电脑一边放歌一边写代码。
各种状态一目了然,值得一提的是"blocked"这个状态:
线程在Running的过程中可能会遇到阻塞(Blocked)情况
- 调用join()和sleep()方法,sleep()时间结束或被打断,join()中断,IO完成都会回到Runnable状态,等待JVM的调度。
- 调用wait(),使该线程处于等待池(wait blocked pool),直到notify()/notifyAll(),线程被唤醒被放到锁定池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)
- 对Running状态的线程加同步锁(Synchronized)使其进入(lock blocked pool ),同步锁被释放进入可运行状态(Runnable)。
此外,在runnable状态的线程是处于被调度的线程,此时的调度顺序是不一定的。Thread类中的yield方法可以让一个running状态的线程转入runnable。
3)多线程的产生的两种方法
a.继承Thread类
b.使用Runnable接口
接下来用一个蚂蚁吃蛋糕的例子分别用两种方法进行演示
Extends方法:
Ant.java
public class Ant extends Thread {
String name;
Cake cake;
public Ant(Cake cake,String str)
{
this.cake=cake;
name=str;
}
@Override
public void run() {
int n=2;
setName(name);
while(true){
cake.loseCake(n);
System.out.println(getName()+" 吃了 "+n+"克蛋糕");
System.out.println("还剩"+cake.getSize()+"克蛋糕");
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(cake.getSize()<=0){
System.out.println(getName()+"因为弹尽粮绝而死!");
return ;
}
}
}
}
Cake.java
public class Cake {
int size;
void setSize(int size){
this.size=size;
}
public int getSize(){
return size;
}
void loseCake(int n){
if(size-n>=0)
size-=n;}
}
Main.java
public class Main {
public static void main(String[]args){
Cake cake = new Cake();
int size=10;
cake.setSize(size);
Ant ant1 = new Ant(cake,"白蚂蚁");
Ant ant2 = new Ant(cake,"黑蚂蚁");
ant1.start();
ant2.start();
}
}
Runnable方法:
Main.javapublic static void main(String[] args) {
// TODO Auto-generated method stub
Cake test = new Cake();
test.setCake(10);
Thread RedAnt = new Thread(test);
RedAnt.setName("red ant");
Thread BlaAnt = new Thread(test);
BlaAnt.setName("black ant");
RedAnt.start();
BlaAnt.start();
}
}
//Runnable便于实现变量的共享,而Thread需要用static才能共享
//Thread类也是Runnable接口的子类
///////////////////////////////////////////
public class Cake implements Runnable{
int size;
public void setCake(int c){
size=c;
}
@Override
public void run() {
int m=2;
while(true){
if(size<=0)
{
System.out.println(Thread.currentThread().getName()+"已经弹尽粮绝!");
return;
}
size-=m;
System.out.println(Thread.currentThread().getName()+"吃了"+m+"克");
System.out.println("还剩下"+size+"克");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Bank.java
public class Bank implements Runnable{
int money;
public void setMoney(int s){
money=s;
System.out.println("First Balance:"+money);
}
@Override
public void run() {
// TODO Auto-generated method stub
int in=300;
int out=150;
if(Thread.currentThread().getName()=="cashier")
InorPut(in);
else if(Thread.currentThread().getName()=="accountant")
InorPut(out);
}
private synchronized void InorPut(int n) {
// TODO Auto-generated method stub
int i;
if(Thread.currentThread().getName()=="cashier")
{
for(i=0;i<3;i++)
{
money+=n/3;
System.out.println(Thread.currentThread().getName()+"存入"+n/3);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Second Balance:"+money);
}
else if(Thread.currentThread().getName()=="accountant")
{
for(i=0;i<3;i++)
{
money-=n/3;
System.out.println(Thread.currentThread().getName()+"拿出"+n/3);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Third Balance:"+money);
}
}
}
Main.java
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Bank test = new Bank();
test.setMoney(200);
Thread cashier = new Thread(test);
cashier.setName("cashier");
Thread accountant = new Thread(test);
accountant.setName("accountant");
accountant.start();
cashier.start();
}
}