码迷,mamicode.com
首页 > 编程语言 > 详细

Java基础 笔记(五)

时间:2015-08-20 13:12:02      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:java   线程   

线程:
static void sleep(long 毫秒):睡眠 在指定的毫秒数内让正在执行的线程进入休眠状态(暂停执行)
throws InterruptedException
注意:
1 线程休眠是帮助所有线程获得运行机会的最好的方法
2 线程睡眠自动苏醒,并返回到就绪状态(可运行),不是运行状态。
sleep()指定的时间是休眠后可运行的最短时间,
sleep()方法不能保证该线程到期后就开始运行
3 sleep()是静态方法,只能控制当前正在运行的线程。

线程的优先级:级别越高,机会越多。级别越低机会越少,但是不绝对
最大:10 MAX_PRIORITY
小写:1 MIN_PRIORITY
默认:5 NORM_PRIORITY
setPriority()
getPriority()


join():合并 表示当前线程等待该线程执行完毕,如果该线程未执行完前sleep了,其他线程将不再等待
static yield():当前线程让步。只让步一次,下一次是哪个线程不一定
void interrupt():中断 修改线程中断的标志flag : false–>true
static boolean interrupted():是否被中断的状态 返回flag 擦除 true–>false
main(){
T1 t = new T1();
t.start();
//发出一个中断信号
t.interrupt();//Thread.interrupted() flag: false–>true

}
class T1 extends Thread{
public void run(){
while(!Thread.interrupted()){
….
//如果sleep()时候被中断,会抛出异常
}
System.out.println(“子线程结束”);
}
}


同步:
数据不安全:
1 Runnable接口实现数据共享
2 run方法中共享语句由多行组成
3 run方法阻塞

同步机制:同步锁
表示只能被一个线程执行,中间不能被打断,其他线程只能等待

原理:其实就是锁定一个对象

实现同步的方式:
1)同步代码块:
synchronized(锁){

   }//自动解锁
  种类:
  a 任意对象 Object obj = new Object();//声明了一个锁
    synchronized(obj){

  }

  b this:当前对象:将当前对象当成锁
  synchronized(this){

  }

 特殊:
  synchronized("abc"){

  }

  byte[] b= new byte[];
  synchronized(b){//0个长度的字节数组

 }

  c 运行时的锁
  静态的数据。静态方法调用的时候使用运行时锁
  A.java-->A.class:jvm加载字节码文件
 synchronized(XXX.class){

  }

  2)同步方法:在方法前面加上synchronized关键字
  同步非静态方法,锁定是this对象
 同步静态方法,锁定是XXX.class对象 ----->同一时刻只有一个线程访问该方法

实例:
public class Demo {

public static void main(String[] args) {
    TicketRunnable1 t = new TicketRunnable1();

    Thread t1 = new Thread(t, "A");
    Thread t2 = new Thread(t, "B");
    t1.start();
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    t.flag = false;
    t2.start();

}

static class TicketRunnable1 implements Runnable {

    private int tickets = 10;
    private boolean flag = true;
    private static int sum = 10;

    @Override
    public void run() {

        if (flag) {
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("sale" + sum--);
            }
        } else {
            while (true)
                t();
        }

    }

    // 同步方法:锁定this
    public synchronized void sale() {
        if (tickets > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()
                    + "   ------    " + --tickets);
        } else {
            flag = false;
        }
    }

    // 注意方法的粒度
    // 静态同步方法:对Class进行加锁,在同一时刻只有一个线程使用此方法
    public static synchronized void t() {// TicketRunnable1.class

        if (sum > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()
                    + "   ------    " + --sum);
        }
    }
}

}


死锁:
由于A线程锁住资源A,等待资源B。线程B锁住了资源B,等待资源A,出现了死锁
一个线程的同步代码中启动了另一个同步,两个线程锁交叉使用
实例:
public class Demo {

public static void main(String[] args) {
    MyRunnable mr = new MyRunnable();
    mr.flag = true;// 张三
    Thread t1 = new Thread(mr, "张三");
    t1.start();

    MyRunnable mr1 = new MyRunnable();
    mr1.flag = false;// 李四
    Thread t2 = new Thread(mr1, "李四");
    t2.start();
}

static class MyRunnable implements Runnable {
    private static String bread = "面包"; // 资源A
    private static String milk = "牛奶"; // 资源B
    boolean flag; // 切换
    @Override
    public void run() {
        if (flag) { // 张三
            synchronized (bread) {
        System.out.println(Thread.currentThread().getName()
                        + "已经锁定了面包,还想要牛奶");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (milk) {
        System.out.println(Thread.currentThread().getName()
                            + "已经锁定了面包也拥有了牛奶");
                }
            }
        } else { // 李四
            synchronized (milk) {
        System.out.println(Thread.currentThread().getName()
                        + "已经锁定了牛奶,还想要面包");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (bread) {
                    System.out.println(Thread.currentThread().getName()
                            + "已经锁定了牛奶也拥有了面包");
                }
            }
        }
    }
}

}


生产者-消费者模式:
notify() notifyAll() wait()必须在同步锁中才能出现。
通过锁来指明让持有该线程的对象去等待或者唤醒

Object类:
wait():让线程进入等待状态,放入了线程池,会释放锁
notify():唤醒等待的线程,唤醒线程池中任意一个线程
notifyAll():唤醒线程池中所有的线程
烤鸭
是否有产品:flag
1)没有产品:
if(flag == false)//没有烤鸭
生产者线程生产产品
flag = true;
消费者线程等待
等待():通知生产者生产产品
2)有产品
if(flag == true)
生产者线程:等待消费者消费
消费者线程:
消费
flag = false
生产者负责生产,有生产产品任务
消费者负责消费,有消费产品的任务
生产和消费同时进行—->多线程

实例:
public class Demo {
public static void main(String[] args) {
Duck d = new Duck();
Productor pro = new Productor(d);
Customer cus = new Customer(d);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(cus);
t1.start();
t2.start();
}
}
class Duck {
String name;
int price;
boolean flag; // 标志
@Override
public String toString() {
return “烤鸭 [name=” + name + “, price=” + price + “, flag=” + flag + “]”;
}
}

// 生产者
class Productor implements Runnable {
Duck duck;
Productor(Duck duck) {
this.duck = duck;
}
@Override
public void run() {
while (true) {
synchronized (duck) {
if (duck.flag) {// 当前已经有生产好的烤鸭了
try {
duck.wait();// 等待消费
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 生产产品
duck.name = “北京烤鸭”;
duck.price = 298;
System.out.println(“———”);
System.out.println(“生产烤鸭:” + duck);
duck.flag = true; // 修改标志:已经生产好了
// 唤醒消费者
duck.notify();
}
}
}
}

// 消费者
class Customer implements Runnable {
Duck duck;
Customer(Duck duck) {
this.duck = duck;
}

@Override
public void run() {
    while (true) {
        synchronized (duck) {
            if (!duck.flag) {// 没有产品
                try {
                    duck.wait(); // 等待生产产品
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println("吃烤鸭" + duck);
            System.out.println("-------------");
            duck.flag = false;// 修改标志
            duck.notify();
        }
    }
}

}

public class Demo {

public static void main(String[] args) {
    Room wdm = new Room();
    Pro p = new Pro(wdm);
    Cus c = new Cus(wdm);
    new Thread(p).start();// t1
    new Thread(c).start(); // t2
    new Thread(p).start(); // t3
    new Thread(c).start(); // t4
}

}

class Room {
private String name;
private int price;
private boolean flag;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getPrice() {
    return price;
}

public void setPrice(int price) {
    this.price = price;
}

public boolean isFlag() {
    return flag;
}

public void setFlag(boolean flag) {
    this.flag = flag;
}

public Room(String name, int price, boolean flag) {
    super();
    this.name = name;
    this.price = price;
    this.flag = flag;
}

public Room() {
    super();
}

@Override
public String toString() {
    return "Room [name=" + name + ", price=" + price + ", flag=" + flag
            + "]";
}

// 生产面包 p t1 t3 c t2 t4
public synchronized void productBread(String name, int price) {
    // 已经有产品:while 而不是if
    while (flag) {
        try {
            // System.out.println("当前已经有产品,等待消费中....");
            this.wait();// 等待 t1 t2 t3
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    this.name = name;
    this.price = price;

    System.out.println("生产面包:" + name + "  " + price);
    this.flag = true;
    this.notifyAll();// //////////////////////////
}

// 消费面包
public synchronized void buyBread() {
    while (!flag) {// 没有面包
        try {
            // System.out.println("当前没有生产好的面包,等待中......");
            this.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    System.out.println("消费面包:" + name + "  " + price);
    this.flag = false;// 消费过了,没有产品
    this.notifyAll();

}

}

// 生产者
class Pro implements Runnable {
Room r;

Pro(Room r) {
    this.r = r;
}

int i = 0;

@Override
public void run() {
    while (true) {
        if (i % 2 == 0) {
            r.productBread("毛毛虫", 7);
        } else {
            r.productBread("面包", 10);
        }
        i++;
    }
}

}

// 消费者
class Cus implements Runnable {
Room r;

Cus(Room r) {
    this.r = r;
}

@Override
public void run() {
    while (true) {
        r.buyBread();
    }

}

}


Lock:
synchronized:悲观锁。
lock:乐观锁。

synchronized(对象){//锁定

}//释放锁

使用Lock接口对锁进行单独的描述。

1 创建Lock接口的一个子类—ReentrantLock
使用Lock替代同步代码块
2 需要同步的代码放入lock()和unlock()之间

wait(),notify(),notifyAll()必须出现在同步代码中
Condition接口中提供了相应的方法、
await() signal() signalAll()


线程池:Executor
创建单线程池对象
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new ThreadRunnable());
executor.execute(new ThreadRunnable());
创建同时可以执行的2个线程
Executor e = Executors.newFixedThreadPool(2);
e.execute(new ThreadRunnable());
e.execute(new ThreadRunnable());
e.execute(new ThreadRunnable());


版权声明:本文为博主原创文章,未经博主允许不得转载。

Java基础 笔记(五)

标签:java   线程   

原文地址:http://blog.csdn.net/u011102153/article/details/47805203

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!