创建线程:
package thread;
public class MutiThreadDemo {
public static void main(String[] args) {
SonOfThread s1= new SonOfThread("zhangsan");
SonOfThread s2= new SonOfThread("lisi");
Thread t1 = new Thread(new RunnableImpl());
Thread t2 = new Thread(new RunnableImpl());
/*
* 不论哪种方法都是通过start来启动线程的,启动线程后,JVM会自动调用run方法
* 直接.run()不是启动线程,而是调用run方法。
*/
s1.start();
s2.start();
t1.start();
t2.start();
for(int j=0;j<10;j++){
for(int i=0;i<1000000;i++){}
System.out.println(Thread.currentThread().getName()+"....."+j);
}
}
}
class SonOfThread extends Thread{
/*
* 自定义线程类继承Thread,重写run方法,使用的是Thread类的空参构造方法
*/
private String name;
public SonOfThread(String name) {
super();
this.name = name;
}
@Override
public void run() {
for(int j=0;j<10;j++){
for(int i=0;i<1000000;i++){}
System.out.println(Thread.currentThread().getName()+"....."+j);
}
}
}
class RunnableImpl implements Runnable{
/*
* 定义一个类实现Runnable接口,重写run方法,使用的是Thread类的Thread(Runnable target)
* 构造方法,推荐使用实现接口的创建方式
* 好处是:1、 可将线程任务封装成对象2、避免java单继承的局限性
*/
public void run() {
for(int j=0;j<10;j++){
for(int i=0;i<1000000;i++){}
System.out.println(Thread.currentThread().getName()+"....."+j);
}
}
}
线程安全的单例模式:
package thread;
/*
* 线程安全的懒汉式单例模式,既然为单例就要保证构造方法私有化,提供一
* 个公共的方法可以获取到单例。static说明:既然是懒汉单例模式,那么在
* 该单例还未实例化之前,该类是没有对象的,所以获取对象的getInstance
* 方法不能通过具体的对象来调用,那么就只能定义为static,通过类来调用,
* 而单例的实例化是在getInstance方法中完成的,所以s也应该定义为static。
* 实例化之前加一个判断是为了保证单例,外层加同步锁是了解决线程安全为题,
* 防止出现多个实例,而锁的外层再加一个判断是为了解决效率问题,这样线程
* 执行的时候就不必每次都判断锁,另外一个:即使是有了外层的判断,内层的
* 也不可以省略,因为有可能一个线程执行到第一个判断条件是判断s=null为真,
* 还未拿到锁就失去了cpu的执行权而停止。这时第二个线程也判断s=null为真,
* 那么无论这两个线程谁先拿到锁,如果没有内层的判断,最终都会实例化出两个
* 对象。
*/
public class Singleton {
private static Singleton s = null;
private Singleton(){}
public static Singleton getInstance(){
if(s==null){
synchronized(Singleton.class){
if(s==null){
s = new Singleton();
}
}
}
return s;
}
}