线程、线程匿名内部类、解决线程不安全的方式

来源:互联网 发布:网络会计培训班 编辑:程序博客网 时间:2024/05/21 06:45

线程

线程:正在运行的程序,是程序的执行路径;多线性

进程:是应用程序的载体,程序运行在虚拟机中。一个应用软件对应一个进程。

一个进程包含多个线程,一个线程对应一个进程。

好处:提高软件的运行效率

多线程的运行原理

在同一时刻只能有一个线程正在使用CPU,操作系统设计了CPU的调度方式。

  • 分时调用:平均分配使用CPU的使用时间
  • 抢占式调度:根据线程的优先级分配CPU资源

开发多线程的方式

  • 继承Thread类
  • 实现Runnable接口

Thread类

构造方法:

成员方法:
- int getPriority() 返回线程的优先级。
- String getName() 返回该线程的名称。
- void run()运行线程逻辑的代码
- void start()开启线程,使线程处于就绪状态,等待CPU的调度。

线程使用

定义子线程类(继承Thread或者实现Runable接口),重写run()方法。

创建线程对象,调用start()方法。

子线程

public class DemoThread extends Thread {    public DemoThread(){}    public DemoThread(String name){        super(name);    }    @Override    public void run() {        Thread demo = Thread.currentThread();        String demoName = demo.getName();        System.out.println(demoName);    }}

主线程

public class DemoMain {    public static void main(String[] args) {        Thread main = Thread.currentThread();        String mainName = main.getName();        System.out.println(mainName);        //创建子线程的对象        DemoThread dt=new DemoThread("我是子线程");        dt.start();        System.out.println("主线程");    }}

实现Runnable接口

  1. 定义类实现Runnable接口,重写run()方法(线程执行的代码)
  2. 创建子线程任务对象
  3. 创建子线程对象
  4. 调用start()方法。

子线程

public class DemoRunable implements Runnable{    @Override    public void run() {        System.out.println(Thread.currentThread().getName());    }}

主线程

public class MainRunnable {    public static void main(String[] args) {        //创建子任务        DemoRunable dr=new DemoRunable();        //创建子线程对象        Thread td=new Thread(dr,"子线程");        td.start();    }}

两种方式的区别

  1. 继承Thread类, 任务与子线程代码 耦合(关联性)到一起。
  2. 实现Runnable接口,把任务代码和子线程的代码分开(解耦性强)
  3. 继承扩展性差、不能继承其他的父类,只能继承一个父类。

线程匿名内部类使用

/** *只调用一次线程 * @author YandeHu * */public class DemoInner {    public static void main(String[] args) {        new Thread(){            @Override            public void run() {            System.out.println(Thread.currentThread().getName());            System.out.println("Thread继承子线程匿名内部类的代码");            }        }.start();        Runnable r=new Runnable(){            @Override            public void run() {                System.out.println("Runnable1 匿名自内部对象");            }        };        Thread td=new Thread(r);        td.start();        new Thread(new Runnable(){            @Override            public void run() {                System.out.println("Runnable2 匿名自内部对象");            }        }).start();    }}

解决线程不安全的方式

保证修改共享数据的代码在同一时刻只能一个线程访问,保证线程是同步的。

  1. 使用同步代码块

    1. 使用关键字 syncronized 修改共享代码块
    2. 同步:代码一行一行的往下执行
    3. 异步:多个线程同时执行
    4. 锁对象:任意的对象类型 ,只有线程拿到此对象,才能执行代码。

    public class TiketRunnable implements Runnable {

    int tiketNumber=100;//锁对象 只有获得锁对象的线程才可以执行Object obj=new Object();@Overridepublic void run() {    while(true){        synchronized (obj) {            if(tiketNumber>0){                try {                    Thread.sleep(50);                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                System.out.println("线程"+Thread.currentThread().getName()+" 正在卖"+(tiketNumber--)+"张票");            }        }    }    } }

Lock接口

Lock lock=new ReentrantLock();//重写run方法public void run() {lock.lock(); 同步代码lock.unlock();}

Lock lock=new ReentrantLock();@Overridepublic void run() {    while(true){        lock.lock();        if(tiketNumber>0){            try {                Thread.sleep(50);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }            System.out.println("线程"+Thread.currentThread().getName()+" 正在卖"+(tiketNumber--)+"张票");        }        lock.unlock();    }
原创粉丝点击