Chapter seventeen 嵌入式Java浅谈(1)

17.1 嵌入式Java

对于一名嵌入式开发工程师来说,Java已经成了一门不得不学的语言.本章主要介绍拿出Java的几个重点,例如多线程,Java网络编程以及一些常用的Java类进行分析.通过 一些基础性学习+深度的剖析,为后续的Android应用课程和Android底层系统移植打下基础.



17.1.1Java多线程

说到线程,我们就必须谈谈线程和进程的区别和多线程的意义和使用场景.普遍认为进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位.也就是说线程是进程中的一部分,一个进程包含多个线程在运行。多线程的意义是:更好的利用CPU资源,一般来说,使用场景为多个角色共同协作的环境,例如消费者和店长.

1)并发和并行的区别

  • 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
  • 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,最典型的场景就是我们用电脑一边放歌一边写代码。
Chapter seventeen 嵌入式Java浅谈(1)

2)线程的状态




Chapter seventeen 嵌入式Java浅谈(1)

各种状态一目了然,值得一提的是"blocked"这个状态:
线程在Running的过程中可能会遇到阻塞(Blocked)情况

  1. 调用join()和sleep()方法,sleep()时间结束或被打断,join()中断,IO完成都会回到Runnable状态,等待JVM的调度。
  2. 调用wait(),使该线程处于等待池(wait blocked pool),直到notify()/notifyAll(),线程被唤醒被放到锁定池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)
  3. 对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.java
public class Main {
public 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();
}
}

Cake.java
//一个是类,一个是接口
//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();
}
}
}
}


4)同步实现的方法
a.Synchronized
b.wait和notify
我们这里只演示Synchronized方法

Synchronized:

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();
}
}