java基础 多线程 简单总结

创建线程的第一种方式:继承Thread ,由子类复写run方法。步骤:

  • 1,定义类继承Thread类;
  • 2,目的是复写run方法,将要让线程运行的代码都存储到run方法中;
  • 3,通过创建Thread类的子类对象,创建线程对象;
  • 4,调用线程的start方法,开启线程,并执行run方法。 线程状态:

创建线程的第二种方式:实现一个接口Runnable。 步骤:

  • 1,定义类实现Runnable接口。
  • 2,覆盖接口中的run方法(用于封装线程要运行的代码)。
  • 3,通过Thread类创建线程对象;
  • 4,将实现了Runnable接口的子类对象作为实际参数传递给Thread类中的构造函数。 为什么要传递呢?因为要让线程对象明确要运行的run方法所属的对象。
  • 5,调用Thread对象的start方法。开启线程,并运行Runnable接口子类中的run方法。
线程的状态
  • **新建:start()
  • **运行:具备执行资格,同时具备执行权;
  • **冻结:sleep(time),wait()—notify()唤醒;线程释放了执行权,同时释放执行资格;
  • **临时阻塞状态:线程具备cpu的执行资格,没有cpu的执行权;
  • **消亡:stop()

这篇博客是看完黑马视频教程总结的,如有错误,请多指教

简单代码块

两种方法,线程使用 例如:

public class ThreadTest {
    public static void main(String[] args) {
        //第一种Thread使用方法
        ThreadOne one1 = new ThreadOne();
        one1.start();
        //设计线程名称
        ThreadOne one2 = new ThreadOne("第一种线程名称");
        one2.start();
        //第二种Runnable使用方法
        ThreadTwo two=new ThreadTwo();
        Thread two1=new Thread(two);
        two1.start();
    }
}

/**
 * 第一种方法 继承thread类
 *
 */
class ThreadOne extends Thread {
    public ThreadOne(){}
    //为线程设置名字
    public ThreadOne (String name){
        super.setName(name);//为线程设置名字
    }
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "线程启动");
        super.run();
    }
}

/**
 * 第二种方法,实现Runnable接口
 */
class ThreadTwo implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "线程启动");
    }
}
  • **为什么将Runnable接口的子类对象传递给Thread的构造函数?
    因为,自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去指定对象的run方法,就必须明确run方法所属的对象
  • **实现方式和继承方式有什么区别呢?
    实现方式好处:避免单继承的局限性。
    在定义线程时,建立使用实现方式。
  • **两种方式区别:
    继承Thread:线程代码存放Thread子类方法中。
    实现Runnable,线程代码存在接口的子类的run方法中。

线程同步

为什么要使用线程同步
  • * java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), *

  • * 多条语句在操作同一个县城共享数据是,一个线程对多条语句值执行了一部分,还没有执行完另一个线程参与进来执行,导致共享数据的错误 *

  • * java对于多献臣过的安全问题提供专业的解决方法,就是同步代码块 *
  • ** synchronized(对象){
    需要同步的代码块
    }
同步的前提:
  • * 必须要有两个或者两个以上的线程 *
  • * 必须是多个线程使用同一个锁(同一个对象) *
这样做
  • ** 好处:结局了多线程的安全问题
  • ** 弊端:多线程需要判断锁,较为消耗资源

注意:如果在run()方法上加锁,那么只有第一个线程会执行,直到执行完后其他的线程才会执行,造成后几个线程分不到任务

简单代码块

线程同步 例如:

/**
 * 线程同步
 */
public class ThreadTest {
    public static void main(String[] args) {
        //线程同步的问题
        ThreadTwo thread = new ThreadTwo();
        Thread thread1 = new Thread(thread);
        Thread thread2 = new Thread(thread);
        Thread thread3 = new Thread(thread);
        Thread thread4 = new Thread(thread);
            thread1.start();
            thread2.start();
            thread3.start();
            thread4.start();
    }
}
/**
 * 实现Runnable接口
 */
class ThreadTwo implements Runnable {
    private static int count = 100;
    @Override
    // 如果在run()方法上加锁,那么只有第一个线程会执行,直到执行完后其他的线程才会执行,造成后几个线程分不到任务
    // public synchronized void run() {
    public void run() {
        while (true) {
            synchronized (this) {
                // 如果是实现Runnable接口,而且只创建一个对象可以用自身的对象区锁住
                if (count == 0) {
                    System.out.println("到0了!");
                    break;
                }
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(count-- + "=========" + Thread.currentThread().getName() + " id:"
                        + Thread.currentThread().getId());
            }
        }
    }
}

如果同步函数是静态

  • ** 静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。XXX.class该对象的类型是Class

简单代码块

两种方法,线程使用 例如:

/**
 * 线程同步
 */
public class ThreadTest {
    public static void main(String[] args) {
        // 线程同步的问题
        ThreadTwo thread = new ThreadTwo();
        Thread thread1 = new Thread(thread);
        Thread thread2 = new Thread(thread);
        Thread thread3 = new Thread(thread);
        Thread thread4 = new Thread(thread);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }
}

/**
 * 实现Runnable接口
 */
class ThreadTwo implements Runnable {
    private static int count = 100;
    private static boolean flag=true;
    @Override
    public void run() {
         while (flag) {
            synchronized (ThreadTwo.class) {
                method();
            }
        }
    }
    //当方法为静态是要用xxx.class锁定
    public static  void method() {
        if(count>0){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(
                    count-- + "=========" + Thread.currentThread().getName() + " id:" + Thread.currentThread().getId());
        }else{
            System.out.println(Thread.currentThread().getName() + "到0了!");
            flag=false;
        }
    }
}
在单例设计模式中有一个饿汉式采用类的字节码对象同步
/**
 * 饿汉式
 * @author chris
 *
 */
class  Single {
    private static final Single single =new Single();
    private Single(){}
    public Single getInstance(){
        return single;
    }
}
/**
 *懒汉式
 * @author chris
 *
 */
class Single2{
    private static Single2 single=null;
    private Single2(){}
    public static Single2 getInstance(){
        if(single!=null){//两次判断提高性能,避免每次都判断锁
            synchronized(Single2.class){
                //用该类的字节码对象同步 解决多线程下出问题
                if(single!=null){
                    single=new Single2();
                }
            }
        }
        return single;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值