Java中Thread的使用、死锁以及生产者消费者问题详解
2012-04-13 18:19
1011 查看
线程的创建主要有四种方式,一种是直接继承Thread实现,另一种是引用接口Runable。这两种创建的线程可以多次使用。也可以运用内部类实现接口的创建。但是用这种方法创建的线程只能用一次。以下就是线程的四种创建方式的相关代码:
当想让线程暂时暂停,进入休眠状态,可以用Sleep实现,该方法是静态方法,可以直接被Thread引用。可以在方法中设置休眠的时间。下面通过一个例子来说明Sleep的用法
当想让一个线程先执行完再去执行另一个线程时,可以用Join方法将当前线程先执行完。下面通过一个例子来说明Join的用法。
当需要一个线程让出当前执行状态即CPU,给其他线程执行的机会,就需要使用Yield方法,使当前线程暂时阻塞,让程序去执行其他的线程。还是通过一个例子来说明。
判断当前线程是否还在执行可以使用Thread.currentThread().isAlive()实现。
如果想让某一个线程的优先级优先,可以通过setPriority来设置线程的优先级。当然也会有一个getPriority来获取优先级MinPriority=1,MaxPriority=10,NomPriority=5。下面通过一个例子来说明setPriority的用法。
如果想实现当一个线程在占用一个资源时,不让别的线程来抢占资源,可以使用synchronized来修饰方法或者语句块,这样别的线程就不会进入synchronized修饰的方法或者方法块。
wait()和sleep()的区别:
<1>wait()时别的线程可以访问锁定对象。
<2>调用该方法时必须锁定该对象。
<3>sleep()时别的线程不可以访问锁定对象。
如果两个线程互相占用对方资源,那么线程将会进入死锁状态,在实现线程时,应该尽量避免死锁情况。下面就是一个典型的死锁例子,在编程时,我们应该要避免死锁的发生。
死锁例子:
通过以上所学的知识,我们就可以实现生活中常遇到的一个生产者消费者问题。下面我就通过一个实例来对这个问题进行下说明。
生产者消费者问题:
以上就是有关线程的全部内容,在以后的编程中我们会经常用到线程,所以这方面的知识要牢牢掌握。
原文地址: http://www.cnblogs.com/zxl-jay/archive/2011/09/25/2189930.html
package java819; public class TestThread { public static void main(String[] args) { MyThread1 mt = new MyThread1(); MyThread2 mt2 = new MyThread2(); mt.start(); new Thread(mt2).start(); new Thread() {//内部类实现 public void run() { for (int i = 0; i < 100; i++) { System.out.println("++++线程3++++++" + i); } } }.start(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("******线程4****" + i); } } }).start(); for (int i = 0; i < 100; i++) { System.out.println("******主线程****" + i); } } } /** * * 四种方法实现线程的创建,两种运用的是内部类 一种是实现接口,一种是继承线程 * */ class MyThread1 extends Thread { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("++++线程一++++++" + i); } } } class MyThread2 implements Runnable { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("-----线程二-------" + i); } } }
当想让线程暂时暂停,进入休眠状态,可以用Sleep实现,该方法是静态方法,可以直接被Thread引用。可以在方法中设置休眠的时间。下面通过一个例子来说明Sleep的用法
1 package java819; 2 import java.io.IOException; 3 import java.nio.CharBuffer; 4 public class TestSleep { 5 public static void main(String[] args) { 6 Runner r = new Runner(); 7 Thread t1 = new Thread(r); 8 Thread t2 = new Thread(r); 9 t1.start(); 10 t2.start(); 11 } 12 } 13 class Runner implements Runnable { 14 @Override 15 public void run() { 16 for (int i = 0; i < 200; i++) { 17 if (i % 10 == 0 && i != 0) { 18 try { 19 Thread.sleep(1000); //Sleep的用法 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } 23 } 24 System.out.println("——————————线程————————————" + i); 25 } 26 } 27 }
当想让一个线程先执行完再去执行另一个线程时,可以用Join方法将当前线程先执行完。下面通过一个例子来说明Join的用法。
package cn.yj3g; public class TestJoin { public static void main(String[] args) { MyThread2 t1 = new MyThread2("zhangcun"); t1.start(); try { t1.join();//先执行调用join方法的线程对象的run方法,完成后才调用这条语句所在的线程 } catch (InterruptedException e) { e.printStackTrace(); } for (int i = 1; i <= 10; i++) { System.out.println("------i am main thread"); } } } class MyThread2 extends Thread { MyThread2(String s) { super(s); } public void run() { for (int i = 1; i <= 10; i++) { System.out.println("I am " + getName()); try { sleep(1000); } catch (InterruptedException e) { System.out.println("又被打爆了!"); return; } } } }
当需要一个线程让出当前执行状态即CPU,给其他线程执行的机会,就需要使用Yield方法,使当前线程暂时阻塞,让程序去执行其他的线程。还是通过一个例子来说明。
1 package java819; 2 public class TestYield { 3 public static void main(String[] args) { 4 MyYield my1 = new MyYield(); 5 MyYield2 my2 = new MyYield2(); 6 my1.start(); 7 my2.start(); 8 9 } 10 } 11 class MyYield extends Thread { 12 @Override 13 public void run() { 14 for (int i = 0; i < 100; i++) { 15 System.out.println("数字为:" + i); 16 if (i % 10 == 0 && i != 0) { 17 yield(); 18 } 19 } 20 } 21 } 22 class MyYield2 extends Thread { 23 @Override 24 public void run() { 25 for (int i = 0; i < 100; i++) { 26 System.out.println("线程二数字为:" + i); 27 if (i % 10 == 0 && i != 0) { 28 yield(); 29 } 30 } 31 } 32 }
判断当前线程是否还在执行可以使用Thread.currentThread().isAlive()实现。
如果想让某一个线程的优先级优先,可以通过setPriority来设置线程的优先级。当然也会有一个getPriority来获取优先级MinPriority=1,MaxPriority=10,NomPriority=5。下面通过一个例子来说明setPriority的用法。
package java819; public class TestPriority { public static void main(String[] args) { T1 t = new T1(); T2 tt = new T2(); tt.setPriority(Thread.NORM_PRIORITY + 4);//设置线程的优先级来改变线程的优先级 t.start(); tt.start(); } } class T1 extends Thread { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("线程T1" + i); } } } class T2 extends Thread { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println("--------线程T2" + i); } } }
如果想实现当一个线程在占用一个资源时,不让别的线程来抢占资源,可以使用synchronized来修饰方法或者语句块,这样别的线程就不会进入synchronized修饰的方法或者方法块。
wait()和sleep()的区别:
<1>wait()时别的线程可以访问锁定对象。
<2>调用该方法时必须锁定该对象。
<3>sleep()时别的线程不可以访问锁定对象。
如果两个线程互相占用对方资源,那么线程将会进入死锁状态,在实现线程时,应该尽量避免死锁情况。下面就是一个典型的死锁例子,在编程时,我们应该要避免死锁的发生。
死锁例子:
1 package java819; 2 public class TestDeadLock implements Runnable { 3 public int flag = 1; 4 static Object o1 = new Object(), o2 = new Object(); 5 @Override 6 public void run() { 7 System.out.println("flag=" + flag); 8 if (flag == 1) { 9 synchronized (o1) { 10 try { 11 Thread.sleep(500); 12 } catch (Exception e) { 13 e.printStackTrace(); 14 } 15 synchronized (o2) { 16 System.out.println("1"); 17 } 18 } 19 } 20 if (flag == 0) { 21 synchronized (o2) { 22 try { 23 Thread.sleep(500); 24 } catch (Exception e) { 25 e.printStackTrace(); 26 } 27 synchronized (o1) { 28 System.out.println("0"); 29 } 30 } 31 } 32 } 33 public static void main(String[] args) { 34 TestDeadLock td1 = new TestDeadLock(); 35 TestDeadLock td2 = new TestDeadLock(); 36 td1.flag = 1; 37 td2.flag = 0; 38 Thread t1 = new Thread(td1); 39 Thread t2 = new Thread(td2); 40 t1.start(); 41 t2.start(); 42 } 43 }
通过以上所学的知识,我们就可以实现生活中常遇到的一个生产者消费者问题。下面我就通过一个实例来对这个问题进行下说明。
生产者消费者问题:
package cn.yj3g; public class TestPC { public static void main(String[] args) { PizzaStack ps = new PizzaStack(); Thread t1 = new Thread(new Cooker(ps)); Thread t3 = new Thread(new Cooker(ps)); Thread t5 = new Thread(new Cooker(ps)); Thread t2 = new Thread(new Customer(ps)); Thread t4 = new Thread(new Customer(ps)); t1.start(); t3.start(); t2.start(); t4.start(); t5.start(); } } /* * 厨子 */ class Cooker implements Runnable { PizzaStack ps; public Cooker(PizzaStack ps) { this.ps = ps; } @Override public void run() { ps.push(); } } /* * 食客 */ class Customer implements Runnable { PizzaStack ps; public Customer(PizzaStack ps) { this.ps = ps; } @Override public void run() { ps.pop(); } } /* * pizza */ class Pizza { int id; public Pizza(int id) { this.id = id; } public String toString() { return "pizza "+id; } } /* * pizza筐 */ class PizzaStack { //栈 private Pizza[] ps = new Pizza[10]; int size; public void push() { while(size>=0 && size<ps.length) { synchronized (this) {//此语句块锁住 this.notifyAll();//唤醒所有线程 Pizza p = new Pizza(size); ps[size++] = p; System.out.println("+++++++生产了"+p+" 剩下"+size+"个"); } try { Thread.sleep((long)(Math.random()*1000)); } catch (InterruptedException e) { e.printStackTrace(); } } try { synchronized (this) { wait(); } } catch (InterruptedException e) { } push(); } public void pop() { while(size>0 && size<=ps.length) { synchronized(this) { this.notifyAll(); Pizza p = ps[--size]; System.out.println("------消费了"+p+" 剩下"+size+"个"); } try { Thread.sleep((long)(Math.random()*1000)); } catch (InterruptedException e) { e.printStackTrace(); } } try { synchronized (this) { wait(); } } catch (InterruptedException e) { } pop(); } }
以上就是有关线程的全部内容,在以后的编程中我们会经常用到线程,所以这方面的知识要牢牢掌握。
原文地址: http://www.cnblogs.com/zxl-jay/archive/2011/09/25/2189930.html
相关文章推荐
- Java中Thread的使用、死锁以及生产者消费者问题详解
- java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
- java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
- JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题
- java 生产者消费者问题以及线程池的使用
- java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
- JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题
- Java 多线程编程(生产者和消费者问题以及死锁)
- JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题
- 生产者消费者问题简单解决之ArrayBlockingQueue的详解与使用
- java中使用阻塞队列解决生产者消费者问题
- 生产者和消费者问题学习以及Java实现
- [Java] Thread-05- 线程同步-生产者与消费者的经典问题
- Java实现生产者消费者问题与读者写者问题详解
- Java 生产者/消费者问题实例详解
- java使用多线程实现生产者消费者问题
- 使用Java实现的简易“生产者消费者问题”
- 再谈java线程以及经典的生产者,消费者问题
- Java并发编程-10-在锁中使用多条件-生产者消费者问题
- java 多线程 详解 生产者消费者 问题解决