首页 > 代码库 > 多线程

多线程

Java.lang包,Thread类,Runnable接口。

创建线程的两种方式

方式一:继承Thread类

1.定义类继承Thread类;

2.子类覆盖父类中的run方法,将线程运行的代码存放在run中;

3.建立子类对象的同时线程也被创建;

4.通过调用start方法开启线程。

public class MyThread extends Thread{    public void run(){        //运行代码;    }}public class ThreadDemo {    MyThread mt = new MyThread();    mt.start();}

方式二:实现Runnable接口(建议使用该方式)

1.定义类实现Runnable接口;

2.覆盖Runnable接口中的run方法,将线程运行的代码存放在run中;

3.通过Thread类建立线程对象;

4.将runnable接口的子类对象作为实际参数传递给Thread类的构造函数;

5.调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

public class MyThread implements Runnable{    public void run(){        //运行代码;    }}public class ThreadDemo {    MyThread mt = new MyThread();    Thread t = new Thread(mt);    t.start();}

多线程的运行存在安全问题,原因:

当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。

解决办法:同步。

同步的前提:

1.必须要有两个或者两个以上的线程;

2.必须是多个线程使用同一个锁。

同步有两种方式

同步方式一:同步代码块

Synchronized(对象){    //需要被同步的代码;}

同步方式二:同步函数

Public synchronized void show(){    //需要被同步的代码;}
 
同步代码块使用的锁是对象:Object obj = new Object();synchronized(obj){}   ;同步函数使用的锁是:this;同步函数被静态static修饰后,使用的锁是:该方法所在类的字节码文件对象,类名.class,该对象的类型是Class。

设计模式:解决某一类问题最行之有效的方法,Java中共有23种设计模式。

设计模式之一:单例设计模式,解决一个类在内存中只存在一个对象。

有两种方式:饿汉式和懒汉式,建议使用饿汉式,懒汉式存在安全问题,需同步。

饿汉式,先初始化对象:

class Single{    private Single(){} //1.将构造函数私有化,禁止其他程序建立该类对象;    private static final Single s = new Single(); //在类中建立一个本类对象;    public static Single getInstance(){ //提供一个方法,方便其他程序可以获取并访问该对象。        return s;    }     ......}class SingleDemo{    public static void main(String[] args){            Single ss = Single.getInstance();    }    ......}

懒汉式,方法被调用时,对象才初始化:

class Single{    private Single(){} //1.将构造函数私有化,禁止其他程序建立该类对象;    private static Single s = null; //在类中建立一个本类对象;    public static Single getInstance(){ //提供一个方法,方便其他程序可以获取并访问该对象。        if(s == null){            s = new Single();         }        return s;    }     ......}class SingleDemo{    public static void main(String[] args){        Single ss = Single.getInstance();    }    ......}

懒汉式的特点在于实例的延迟加载,通过多线程访问时会出现安全问题,可以加同步来解决,加同步的方式,用同步代码块和同步函数都行,但是稍微有些低效,用双重判断的形式能解决效率问题,加同步的时候使用的锁是:该类所属的字节码文件对象。如下:

class Single{    private Single(){}     private static Single s = null;     public static Single getInstance(){         if(s == null){            Synchronized(Single.class) { //静态方法的锁:类名.class                if(s == null){                    s = new Single();                 }            }        }        return s;    }     ......}