襄樊牛杂面红油配方:java线程基础
来源:百度文库 编辑:九乡新闻网 时间:2024/07/07 15:25:47
java多线程
文章分类:Java编程 1. 创建线程的两种方式2. 线程的生命周期
3. 同步的方式
4. 死锁
5. 生产消费模型、监控模型
创建线程的两种方式
Java代码
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_1.gif)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_2.png)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_3.gif)
- public class Thread1 extends Thread {
- private int j;
- // 重写run方法
- public void run() {
- for (; j < 100; j++) {
- System.out.println(getName() + " " + j);
- }
- }
- // 主函数
- public static void main(String args[]) {
- for (int i = 0; i < 100; i++) {
- // 打印主线程执行信息
- System.out.println(Thread.currentThread().getName() + " " + i);
- if (i == 20) {
- // 新启两个线程
- new Thread1().start();
- new Thread1().start();
- }
- }
- }
- }
- public class Thread2 implements Runnable {
- private int j;
- // 实现run方法
- public void run() {
- for (; j < 100; j++) {
- System.out.println(Thread.currentThread().getName() + " " + j);
- }
- }
- // 主方法
- public static void main(String args[]) {
- for (int i = 0; i < 100; i++) {
- // 打印主线程执行信息
- System.out.println(Thread.currentThread().getName() + " " + i);
- if (i == 20) {
- // 新启两个线程
- Thread2 thread=new Thread2();
- new Thread(thread,"新线程1").start();
- new Thread(thread,"新线程2").start();
- }
- }
- }
- }
public class Thread1 extends Thread {private int j;// 重写run方法public void run() {for (; j < 100; j++) {System.out.println(getName() + " " + j);}}// 主函数public static void main(String args[]) {for (int i = 0; i < 100; i++) {// 打印主线程执行信息System.out.println(Thread.currentThread().getName() + " " + i);if (i == 20) {// 新启两个线程new Thread1().start();new Thread1().start();}}}}public class Thread2 implements Runnable {private int j;// 实现run方法public void run() {for (; j < 100; j++) {System.out.println(Thread.currentThread().getName() + " " + j);}}// 主方法public static void main(String args[]) {for (int i = 0; i < 100; i++) {// 打印主线程执行信息System.out.println(Thread.currentThread().getName() + " " + i);if (i == 20) {// 新启两个线程Thread2 thread=new Thread2();new Thread(thread,"新线程1").start();new Thread(thread,"新线程2").start();}}}}
结果:
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_4.jpg)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_5.jpg)
从图片上我们可以看到,第一张图片数据之间没有实现共享,但是第二张图片,我们可以看到线程1和线程2共享了线程类的实例属性,这是因为程序所创建的Runnable对象只是线程的的target,而多个线程可以共享一个target;
对于用继承Thread和实现Runnable,采用Runnable的话该实现类还可以进行继承,扩展性更强;
启动一个线程用的是start(),而不是run();如果直接用run()则会将它当作一个普通的方法来使用;用start(),则会将run方法当作线程执行体来处理;
前面的两个示例,实际上至少有三条线程,主线程和程序显示创建的两条线程;主线程的线程执行体不是由run方法来确定的,而是由main方法来确定的
线程的生命周期
当程序用new关键字创建一个线程之后,该线程就处于新建状态,此时它和其它Java对象一样,仅仅由Java虚拟机为其分配内存,并初始化了其成员变量的值。当线程调用了start方法后,该线程处于就绪状态;
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_6.jpg)
同步的方式
一.synchronized关键字保证同步
锁定方法:表示这个方法同时只能被一个线程访问
Java代码
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_1.gif)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_2.png)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_3.gif)
- //同步方法 同步监视器为this
- public synchronized int getM1(int count){
- return 1;
- }
//同步方法 同步监视器为thispublic synchronized int getM1(int count){return 1;}
锁定对象:表示其限定的代码块只能同时被一个线程访问
Java代码
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_1.gif)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_2.png)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_3.gif)
- //同步代码块
- public void getM2(){
- synchronized(obj){
- //代码块,obj为同步监视器
- }
- }
//同步代码块public void getM2(){synchronized(obj){//代码块,obj为同步监视器}}
二.新用JDK1.5新的同步机制
Java代码
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_1.gif)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_2.png)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_3.gif)
- private Lock lock=new ReentrantLock();
- //在方法内使用同步锁
- public void getM3(){
- //开始锁
- lock.lock();
- //同步区。。。
- try{
- }finally{
- //释放锁
- lock.unlock();
- }
- }
private Lock lock=new ReentrantLock();//在方法内使用同步锁public void getM3(){//开始锁lock.lock();//同步区。。。try{}finally{//释放锁lock.unlock();}}
死锁
当两线程相互等待对方释放同步监视器时就会出现死锁,一旦出现死锁,整个程序既不会发生任何的异常,也不会给出任何的提示,只是所有线程处理阻塞状态,无法继续
Java代码
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_1.gif)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_2.png)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_3.gif)
- class A {
- synchronized void foo(B b) {
- String name = Thread.currentThread().getName();
- System.out.println(name + " entered A.foo");
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- System.out.println("A Interrupted");
- }
- System.out.println(name + " trying to call B.last()");
- // 因为b对象被锁住了,调用b内的方法时,在等锁的释放
- b.last();
- }
- synchronized void last() {
- System.out.println("Inside A.last");
- }
- }
- class B {
- synchronized void bar(A a) {
- String name = Thread.currentThread().getName();
- System.out.println(name + " entered B.bar");
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- System.out.println("B Interrupted");
- }
- System.out.println(name + " trying to call A.last()");
- // 因为a对象被锁住了,调用a内的方法时,在等锁的释放
- a.last();
- }
- synchronized void last() {
- System.out.println("Inside A.last");
- }
- }
- class Deadlock implements Runnable {
- A a = new A();
- B b = new B();
- Deadlock() {
- Thread.currentThread().setName("MainThread");
- Thread t = new Thread(this, "RacingThread");
- t.start();
- a.foo(b); // 同步监视器为a
- System.out.println("Back in main thread");
- }
- public void run() {
- b.bar(a); // 同步监视器为b
- System.out.println("Back in other thread");
- }
- public static void main(String args[]) {
- new Deadlock();
- }
- }
class A {synchronized void foo(B b) {String name = Thread.currentThread().getName();System.out.println(name + " entered A.foo");try {Thread.sleep(1000);} catch (Exception e) {System.out.println("A Interrupted");}System.out.println(name + " trying to call B.last()");// 因为b对象被锁住了,调用b内的方法时,在等锁的释放b.last();}synchronized void last() {System.out.println("Inside A.last");}}class B {synchronized void bar(A a) {String name = Thread.currentThread().getName();System.out.println(name + " entered B.bar");try {Thread.sleep(1000);} catch (Exception e) {System.out.println("B Interrupted");}System.out.println(name + " trying to call A.last()");// 因为a对象被锁住了,调用a内的方法时,在等锁的释放a.last();}synchronized void last() {System.out.println("Inside A.last");}}class Deadlock implements Runnable {A a = new A();B b = new B();Deadlock() {Thread.currentThread().setName("MainThread");Thread t = new Thread(this, "RacingThread");t.start();a.foo(b); // 同步监视器为aSystem.out.println("Back in main thread");}public void run() {b.bar(a); // 同步监视器为bSystem.out.println("Back in other thread");}public static void main(String args[]) {new Deadlock();}}
生产消费模型、监控模型
Java代码
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_1.gif)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_2.png)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_3.gif)
- //生产消费模型
- public class Main {
- public static void main(String args[]) {
- List
list = new ArrayList (); - new Product(list).start();
- new Customer(list).start();
- }
- }public class Egg {
- private int id;
- private String name;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String toString() {
- return id + " " + name;
- }
- }public class Product extends Thread {
- private List
list; - private int count;
- public Product(List
list) { - this.list = list;
- }
- // 重写run方法
- public void run() {
- System.out.println("生产线程启动");
- while (true) {
- try {
- Thread.sleep(100);
- synchronized (list) {
- //还有鸡蛋时
- while (list.size() > 0) {
- list.wait();
- }
- //没有鸡蛋时
- while(list.size()==0){
- Egg egg=new Egg();
- egg.setId(count++);
- egg.setName("鸡蛋");
- System.out.println("生产线程生产"+egg.toString());
- list.add(egg);
- //通知消费线程
- list.notify();
- }
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }public class Customer extends Thread {
- private List
list; - public Customer(List
list) { - this.list = list;
- }
- // 重写run方法
- public void run() {
- System.out.println("消费线程启动");
- while (true) {
- try {
- Thread.sleep(100);
- synchronized (list) {
- //没有则等待
- while (list.size() == 0) {
- list.wait();
- }
- //有鸡蛋时
- while(list.size()>0){
- System.out.println("消费线程消费"+list.remove(0).toString());
- //通知生产线程
- list.notify();
- }
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
//生产消费模型public class Main {public static void main(String args[]) {Listlist = new ArrayList ();new Product(list).start();new Customer(list).start();}}public class Egg {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String toString() {return id + " " + name;}}public class Product extends Thread {private List list;private int count;public Product(List list) {this.list = list;}// 重写run方法public void run() {System.out.println("生产线程启动");while (true) {try {Thread.sleep(100);synchronized (list) {//还有鸡蛋时while (list.size() > 0) {list.wait();}//没有鸡蛋时while(list.size()==0){Egg egg=new Egg();egg.setId(count++);egg.setName("鸡蛋");System.out.println("生产线程生产"+egg.toString());list.add(egg);//通知消费线程list.notify();}}} catch (InterruptedException e) {e.printStackTrace();}}}}public class Customer extends Thread {private List list;public Customer(List list) {this.list = list;}// 重写run方法public void run() {System.out.println("消费线程启动");while (true) {try {Thread.sleep(100);synchronized (list) {//没有则等待while (list.size() == 0) {list.wait();}//有鸡蛋时while(list.size()>0){System.out.println("消费线程消费"+list.remove(0).toString());//通知生产线程list.notify();}}} catch (InterruptedException e) {e.printStackTrace();}}}}
Java代码
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_1.gif)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_2.png)
![](http://image25.360doc.cn/DownloadImg/2011/03/2415/10307936_3.gif)
- //监控模型public class Control implements Runnable {
- // 存放统计线程的队列
- private static List
list = new ArrayList (); - // 主函数
- public static void main(String args[]) {
- // 取得系统的根目录个数
- java.io.File[] dirF = java.io.File.listRoots();
- // 根据目录创建统计纯种个数
- for (int i = 0; i < dirF.length; i++) {
- CountFile cf = new CountFile(dirF[i].getAbsolutePath());
- cf.start();
- list.add(cf);
- }
- System.out.println(dirF.length + " 个统计线程已启动");
- // 启动监视线程
- new Thread(new Control()).start();
- System.out.println("监视线程已启动");
- }
- // 实现run方法
- public void run() {
- boolean flag = true;
- String result = "";
- while (flag) {
- for (int i = 0; i < list.size(); i++) {
- if (list.get(i).isFinished()) {
- // 取得统计结果
- result += list.get(i).getResult();
- // 移出统计完的线程
- list.remove(i);
- }
- }
- // 全部统计完
- if (list.isEmpty()) {
- flag = false;
- }
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- System.out.println("统计结果如下:");
- System.out.println(result);
- }
- }public class CountFile extends Thread {
- private String root;// 进行搜索的根目录的名字
- private int lengthCount;// 所有文件长度
- private int dirCount;// 目录数
- private int realFileCount;// 统计的真正文件数量
- private boolean finished = false;
- // 构造时传入搜索根目录名
- public CountFile(String root) {
- this.root = root;
- }
- /**
- * 查看线程是否统计结束
- *
- * @return
- */
- public boolean isFinished() {
- return finished;
- }
- /**
- * 返回统计结果
- *
- * @return
- */
- public String getResult() {
- StringBuffer result = new StringBuffer();
- result.append(root + "盘统计结果如下:\r\n");
- result.append(" 文件数量: " + realFileCount);
- result.append(" 目录数: " + dirCount);
- result.append(" 文件总长度(单位K): " + lengthCount / 1204);
- result.append("\r\n");
- return result.toString();
- }
- // 重写run方法
- public void run() {
- long start = System.currentTimeMillis();
- lengthCount = countProcess(root);
- long cost = System.currentTimeMillis() - start;
- finished = true;
- }
- /**
- * 统计目录下文件的长度
- *
- * @param root
- * 要统计的目录
- * @return 目录下文件的长度
- */
- private int countProcess(String root) {
- int count = 0;
- File dirFile = new File(root);
- // 目录不存在
- if (!dirFile.exists()) {
- return count;
- }
- // 获得目录下的所有文件组成的数组
- File[] subFile = dirFile.listFiles();
- if (subFile == null) {
- return count;
- }
- // 对这个数组进行遍历
- for (int i = 0; i < subFile.length; i++) {
- // 是个目录
- if (subFile[i].isDirectory()) {
- dirCount++;
- count += countProcess(subFile[i].getAbsolutePath());// 用递归计算该目录下的文件长度
- }
- // 是一个文件
- if (subFile[i].isFile()) {
- realFileCount++;
- count += subFile[i].length();
- }
- }
- return count;
- }
- }
//监控模型public class Control implements Runnable {// 存放统计线程的队列private static Listlist = new ArrayList ();// 主函数public static void main(String args[]) {// 取得系统的根目录个数java.io.File[] dirF = java.io.File.listRoots();// 根据目录创建统计纯种个数for (int i = 0; i < dirF.length; i++) {CountFile cf = new CountFile(dirF[i].getAbsolutePath());cf.start();list.add(cf);}System.out.println(dirF.length + " 个统计线程已启动");// 启动监视线程new Thread(new Control()).start();System.out.println("监视线程已启动");}// 实现run方法public void run() {boolean flag = true;String result = "";while (flag) {for (int i = 0; i < list.size(); i++) {if (list.get(i).isFinished()) {// 取得统计结果result += list.get(i).getResult();// 移出统计完的线程list.remove(i);}}// 全部统计完if (list.isEmpty()) {flag = false;}try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}}System.out.println("统计结果如下:");System.out.println(result);}}public class CountFile extends Thread {private String root;// 进行搜索的根目录的名字private int lengthCount;// 所有文件长度private int dirCount;// 目录数private int realFileCount;// 统计的真正文件数量private boolean finished = false;// 构造时传入搜索根目录名public CountFile(String root) {this.root = root;}/*** 查看线程是否统计结束** @return*/public boolean isFinished() {return finished;}/*** 返回统计结果** @return*/public String getResult() {StringBuffer result = new StringBuffer();result.append(root + "盘统计结果如下:\r\n");result.append(" 文件数量: " + realFileCount);result.append(" 目录数: " + dirCount);result.append(" 文件总长度(单位K): " + lengthCount / 1204);result.append("\r\n");return result.toString();}// 重写run方法public void run() {long start = System.currentTimeMillis();lengthCount = countProcess(root);long cost = System.currentTimeMillis() - start;finished = true;}/*** 统计目录下文件的长度** @param root* 要统计的目录* @return 目录下文件的长度*/private int countProcess(String root) {int count = 0;File dirFile = new File(root);// 目录不存在if (!dirFile.exists()) {return count;}// 获得目录下的所有文件组成的数组File[] subFile = dirFile.listFiles();if (subFile == null) {return count;}// 对这个数组进行遍历for (int i = 0; i < subFile.length; i++) {// 是个目录if (subFile[i].isDirectory()) {dirCount++;count += countProcess(subFile[i].getAbsolutePath());// 用递归计算该目录下的文件长度}// 是一个文件if (subFile[i].isFile()) {realFileCount++;count += subFile[i].length();}}return count;}}
- 大小: 4.9 KB
- 大小: 5.7 KB
- 大小: 37.9 KB
java线程基础
Java中的线程组
java线程方法概述
进程和线程基础
java笔试题之线程、JSP部分
java基础面试题
java基础概述
Java学习总结之第一章Java基础
Java 理论与实践: 线程池与工作队列
Java免费教程 Java源码下载 Java控件 Java实例基础 Java函数
Java面试题--设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1
JAVA基础:关于Java栈与堆的思考
JAVA开发基础:理解JNI使用原理
Java开发基础:三十条规则
基础加强第五天-- Java 反射
Java数字签名,Java基础,编程开发,Java,好视点技术文档
如果java从零基础开始学,需要多长时间?
对有基础的java程序员应该学什么java书比较好?
java
Java-Web开发基础之html语法基础 - 小雄的博客 - ITeye技术网站
c#线程相关概念
C#教程:线程同步
线程学习之笔记
VC 线程同步