线程

线程的创建方法

  1. 继承Thread父类,重写run方法;
    开启时new一个对象直接调用start()方法开启线程;
  2. 实现Runnable接口,重写run方法;
    开启是先创建一个Thread的对象,在构造方法中写入一个runnable接口,即new Thread(this).start()。
  3. 匿名内部类法,如下
    new Thread(){
           public void run(){

           }
      }.start();

线程的常见方法:


类方法(静态,用类名去调用的方法)


1.sleep(); 休眠方法,会发生中断异常,即ThreadinterruptedException;
2.currentThread(); 获取当前线程;
3.yield();


对象方法(用类的对象去调用的方法)


  1. getName(); 当前线程的名字
  2. getPriority(); 优先级 【1,10】(默认值为5)。 具有较高优先级的线程对程序更重要,并且应该在低优先级的线程之前分配处理器时间。然而,线程优先级不能保证线程执行的顺序,而且非常依赖于平台。
  3. setDaemon(true) ; 设置守护线程 GC:垃圾回收器,他是一个守护线程,一般的Thread 都是用户线程

线程安全


线程不安全的前提


  1. 开启多个线程;
  2. 多个线程有公共的资源;
  3. 同时修改。

解决方法


使用同步锁synchronized


  1. 使用同步方法,即用synchronized修饰的方法;
  2. 使用同步代码块,即用synchronized修饰的代码块。

notify()、notifyAll、wait()、sleep()


  1. notify(); 唤醒一个等待线程,进入可执行状态;
  2. wait(); 释放cup,将CPU让出给别的线程使用,并释放同步锁,将此线程 放入等待池;
  3. notifyAll() ; 唤醒所有等待池中的线程;
  4. notify()、notifyAll、wait() 方法被锁对象调用,且在同步方法或同步代码块中调用。
  5. sleep(),会发生中断异常,即ThreadinterruptedException,让出cpu,不释放锁。

实例:妖的故事

String name;
String sex;
Object lock = new Object();
int x = 0;

class Set implements Runnable {
    public void run() {
        while (true) {
          public synchronized void set() {
              if (x == 0) {
                  name = "Mark";
                  sex = "男";
              } else {
                  name = "Lucy";
                  sex = "女";
              }
              notify();
              try {
                  wait();//释放CPU和锁
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              x++;
              x %= 2;
         }
       }
    }
}

class Get implements Runnable {
    public void run() {
        while (true) {
           public synchronized void get() {
               System.out.println(name + "  " + sex);
               notify(); // 唤醒一个wait等待的线程
               try {
                   wait();//释放CPU和锁
               } catch (InterruptedException e) {
                   e.printStackTrace();
                }
           }
        }
    }
}

public static void main(String[] args) {
    Resource resource = new Resource();
    Set set = resource.new Set();
    Get get = resource.new Get();
    new Thread(set).start();
    new Thread(get).start();
}

一个线程的生命周期

线程的几种状态之间的转换:创建(new)、运行(runnable)、阻塞(waiting 、 timed waiting、blocked)和死亡(terminate)。
在给定时间点上,一个线程只能处于一种状态。这些状态是虚拟机状态,它们并没有反映所有操作系统线程状态。



这里写图片描述

单例模式

单例是指该类只能创建一个对象,故将构造方法私有。

package sychronized;

public class SIngletonInstance {

    // 恶汉   在定义的时候new  
    // private static SIngletonInstance instance = new SIngletonInstance();
    // private synchronized static SIngletonInstance getInstance(){
    // return instance;
    // }

    // 懒汉 定义的时候不new   方法体才new
    private static SIngletonInstance instance;

    public SIngletonInstance getInstance() {
        if (instance == null) {
            synchronized (SIngletonInstance.class) {
                if (instance == null) {
                    instance = new SIngletonInstance();
                }
            }
        }
        return instance;

    }
}

死锁问题

在Java中,每一个 Object 对象都有一个隐含的锁,这个也称作监视器对象。在进入 synchronized 之前自动获取此内部锁,而一旦离开此方式,无论是完成或者中断都会自动释放锁;其次若不适用object对象的锁,就可使用<类名.class>获取锁。


死锁问题的产生:

  1. 锁的嵌套使用;
  2. 多个线程公用一把锁,拿到锁后不相让。

package sychronized;

public class ChopSticks extends Thread {

    static String firstChopSticks = new String();
    static String sencondChopSticks = new String();
    String name;

    public ChopSticks(String name) {
        this.name = name;
    }

    public void run() {
        if (name.equals("yi")) {
            synchronized (firstChopSticks) {
                System.out.println("get  first!!");
                synchronized (sencondChopSticks) {
                    System.out.println("get sencond");
                }
            }
        }
        if (name.equals("ji")) {
            synchronized (sencondChopSticks) {
                System.out.println("get sencond");
                synchronized (firstChopSticks) {
                    System.out.println("get  first!!");
                }
            }
        }
    }

    public static void main(String[] args) {
        ChopSticks ch1 = new ChopSticks("yi");
        ChopSticks ch2 = new ChopSticks("ji");
        Thread thread = new Thread(ch2);
        thread.start();
        Thread thread2 = new Thread(ch1);
        thread2.start();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值