线程

来源:互联网 发布:淘宝的畅淘卡怎么办理 编辑:程序博客网 时间:2024/06/05 18:02

线程的创建方法

  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
原创粉丝点击