线程:
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());
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u011102153/article/details/47805203