java基础(三)

来源:互联网 发布:淘宝货源免费代销 编辑:程序博客网 时间:2024/05/08 17:19

java多线程

  • 进程和线程
    • 进程:正在运行的程序,是系统进行资源分配和调用的独立单位。每一个进程都有它自己的内存空间和系统资源。
    • 线程:是进程中的单个顺序控制流,是一条执行路径。一个进程如果只有一条执行路径,则称为单线程程序。一个进程如果有多条执行路径,则称为多线程程序。
  • Java程序运行原理
    • java 命令会启动 java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程。该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 main 方法。所以 main方法运行在主线程中。程序都是单线程的。

线程中一些常用的方法:
线程休眠
public static void sleep(long millis)
线程加入
public final void join()
线程礼让
public static void yield()
后台线程
public final void setDaemon(boolean on)
中断线程
public final void stop()
public void interrupt()


实现多线程的方法

  • 继承Thread类
    • 通过继承Thread类,重写run方法(不重写也可以,但继承了Thread类,就没任何意义了,)

代码:

public class MyThread extends Thread {    // 通过构造方法修改线程名称    public MyThread(String name) {        super(name);    }    @Override    public void run() {    //getName()获取线程的名称        System.out.println("我是线程:" + getName());    }}

  • 实现Runnable接口

    • 通过继承Thread类可以实现多线程,那么为什么实现接口呢?
    • 实现接口方式的好处:可以避免由于Java单继承带来的局限性。适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离,较好的体现了面向对象的设计思想。

    代码:

public class MyThread implements Runnable {    @Override    public void run() {        //getName()获取线程的名称        System.out.println("我是线程:" + Thread.currentThread().getName());    }}class Test {    public static void main(String[] args) {        //此时MyThread类虽然实现了Runnable类,但还没有和多线程有关系        //必须通过Thread类的Thread(Runnable target)构造方法和MyThread关联        MyThread myThread = new MyThread();        Thread thread = new Thread(myThread,"A");        thread.start();    }}


关于多线程的安全问题

  • 当开启了多线程而没有通过任何处理而共享一个数据时会导致数据混乱(比如:电影院售票,会出现:相同的票出现多次,现了负数的票),这样对软件的影响是非常大的。
  • 解决方案
    • 同步代码块:synchronized(对象){需要同步的代码;}
    • 同步方法
    • JDK5后提供了一个新的锁对象Lock

代码:

@Override    public void run() {        //同步代码块        synchronized (obj) {            System.out.println("我是线程:" + Thread.currentThread().getName());        }    }-------------------------------------------------------------//锁对象LockLock lock = new ReentrantLock();// 锁  @Override    public void run() {         lock.lock();// 取得锁            try {                 System.out.println("我是线程:" + Thread.currentThread().getName());            } catch (InterruptedException e) {              }finally {        lock.unlock();// 释放锁       }    }
  • 多线程死锁
    • 是指两个或者两个以上的线程在执行的过程中,因争夺资源产生的一种互相等待现象
      代码:
public void run() {        while (true) {            if(falg){            //拿到obj1后继续拿obj2                synchronized (obj1) {                    System.out.println("---obj1");                    synchronized (obj2) {                        System.out.println("---obj2");                    }                }                falg = false;            }else{            //拿到obj2后继续拿obj1                synchronized (obj2) {                    System.out.println("---obj2");                    synchronized (obj1) {                        System.out.println("---obj1");                    }                }                falg = true;            }        }    }

  • 线程间通信(生产者和消费者)
    • 针对同一个资源的操作有不同种类的线程

代码(生产者):

public class SetThread implements Runnable {    private Student s;    private int x = 0;    public SetThread(Student s) {        this.s = s;    }    @Override    public void run() {        while (true) {            synchronized (s) {                //判断有没有                if(s.flag){                    try {                        s.wait(); //t1等着,释放锁                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                if (x % 2 == 0) {                    s.name = "男人";                    s.age = 27;                } else {                    s.name = "女人";                    s.age = 30;                }                x++; //x=1                //修改标记                s.flag = true;                //唤醒线程                s.notify(); //唤醒消费者,唤醒并不表示立马可以执行,必须还得抢CPU的执行权。            }        }    }}

代码(消费者):

public class GetThread implements Runnable {    private Student s;    public GetThread(Student s) {        this.s = s;    }    @Override    public void run() {        while (true) {            synchronized (s) {                if(!s.flag){                    try {                        s.wait(); //消费者睡眠,立即释放锁。将来醒过来的时候,是从这里醒过来的时候                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                System.out.println(s.name + "---" + s.age);                //修改标记                s.flag = false;                //唤醒线程                s.notify(); //唤醒t1            }        }    }}
  • 多线程中的定时器
    • Timer
      public Timer()
      public void schedule(TimerTask task, long delay)
      public void schedule(TimerTask task,long delay,long period)
    • TimerTask
      public abstract void run()
      public boolean cancel()

代码:

/* * 定时器:可以让我们在指定的时间做某件事情,还可以重复的做某件事情。 * 依赖Timer和TimerTask这两个类: * Timer:定时 *      public Timer() *      public void schedule(TimerTask task,long delay) *      public void schedule(TimerTask task,long delay,long period) *      public void cancel() * TimerTask:任务 */public class MyTimer {    public static void main(String[] args) {        // 创建定时器对象        Timer t = new Timer();        // 3秒后执行爆炸任务第一次,如果不成功,每隔2秒再继续炸        t.schedule(new MyTask(), 3000, 2000);    }}// 做一个任务class MyTask extends TimerTask {    @Override    public void run() {        System.out.println("beng,爆炸了");    }}

总结

java的多线程是很重要的一个模块,特别在android中,刚接触时可能无法理解,但多打代码,多验证自己啲想法,多的积累经验。

0 0
原创粉丝点击