1. 创建线程的两种方式

2. 线程的生命周期

3. 同步的方式

4. 死锁

5. 生产消费模型、监控模型

创建线程的两种方式

Java代码  

publicclassThread1extendsThread {

privateintj;

// 重写run方法

publicvoidrun() {

for(; j <100; j++) {

System.out.println(getName() +" "+ j);

}

}

// 主函数

publicstaticvoidmain(String args[]) {

for(inti =0; i <100; i++) {

// 打印主线程执行信息

System.out.println(Thread.currentThread().getName() +" "+ i);

if(i ==20) {

// 新启两个线程

newThread1().start();

newThread1().start();

}

}

}

}

publicclassThread2implementsRunnable {

privateintj;

// 实现run方法

publicvoidrun() {

for(; j <100; j++) {

System.out.println(Thread.currentThread().getName() +" "+ j);

}

}

// 主方法

publicstaticvoidmain(String args[]) {

for(inti =0; i <100; i++) {

// 打印主线程执行信息

System.out.println(Thread.currentThread().getName() +" "+ i);

if(i ==20) {

// 新启两个线程

Thread2 thread=newThread2();

newThread(thread,"新线程1").start();

newThread(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();

}

}

}

}

结果:

从图片上我们可以看到,第一张图片数据之间没有实现共享,但是第二张图片,我们可以看到线程1和线程2共享了线程类的实例属性,这是因为程序所创建的Runnable对象只是线程的的target,而多个线程可以共享一个target;

对于用继承Thread和实现Runnable,采用Runnable的话该实现类还可以进行继承,扩展性更强;

启动一个线程用的是start(),而不是run();如果直接用run()则会将它当作一个普通的方法来使用;用start(),则会将run方法当作线程执行体来处理;

前面的两个示例,实际上至少有三条线程,主线程和程序显示创建的两条线程;主线程的线程执行体不是由run方法来确定的,而是由main方法来确定的

线程的生命周期

当程序用new关键字创建一个线程之后,该线程就处于新建状态,此时它和其它Java对象一样,仅仅由Java虚拟机为其分配内存,并初始化了其成员变量的值。当线程调用了start方法后,该线程处于就绪状态;

同步的方式

一.synchronized关键字保证同步

锁定方法:表示这个方法同时只能被一个线程访问

Java代码  

//同步方法 同步监视器为this

publicsynchronizedintgetM1(intcount){

return1;

}

//同步方法 同步监视器为this

public synchronized int getM1(int count){

return 1;

}

锁定对象:表示其限定的代码块只能同时被一个线程访问

Java代码  

//同步代码块

publicvoidgetM2(){

synchronized(obj){

//代码块,obj为同步监视器

}

}

//同步代码块

public void getM2(){

synchronized(obj){

//代码块,obj为同步监视器

}

}

二.新用JDK1.5新的同步机制

Java代码  

privateLock lock=newReentrantLock();

//在方法内使用同步锁

publicvoidgetM3(){

//开始锁

lock.lock();

//同步区。。。

try{

}finally{

//释放锁

lock.unlock();

}

}

private Lock lock=new ReentrantLock();

//在方法内使用同步锁

public void getM3(){

//开始锁

lock.lock();

//同步区。。。

try{

}finally{

//释放锁

lock.unlock();

}

}

死锁

当两线程相互等待对方释放同步监视器时就会出现死锁,一旦出现死锁,整个程序既不会发生任何的异常,也不会给出任何的提示,只是所有线程处理阻塞状态,无法继续

Java代码  

classA {

synchronizedvoidfoo(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();

}

synchronizedvoidlast() {

System.out.println("Inside A.last");

}

}

classB {

synchronizedvoidbar(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();

}

synchronizedvoidlast() {

System.out.println("Inside A.last");

}

}

classDeadlockimplementsRunnable {

A a =newA();

B b =newB();

Deadlock() {

Thread.currentThread().setName("MainThread");

Thread t =newThread(this,"RacingThread");

t.start();

a.foo(b);// 同步监视器为a

System.out.println("Back in main thread");

}

publicvoidrun() {

b.bar(a);// 同步监视器为b

System.out.println("Back in other thread");

}

publicstaticvoidmain(String args[]) {

newDeadlock();

}

}

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();

}

}

生产消费模型、监控模型

Java代码  

//生产消费模型

publicclassMain {

publicstaticvoidmain(String args[]) {

List list =newArrayList();

newProduct(list).start();

newCustomer(list).start();

}

}publicclassEgg {

privateintid;

privateString name;

publicintgetId() {

returnid;

}

publicvoidsetId(intid) {

this.id = id;

}

publicString getName() {

returnname;

}

publicvoidsetName(String name) {

this.name = name;

}

publicString toString() {

returnid +" "+ name;

}

}publicclassProductextendsThread {

privateList list;

privateintcount;

publicProduct(List list) {

this.list = list;

}

// 重写run方法

publicvoidrun() {

System.out.println("生产线程启动");

while(true) {

try{

Thread.sleep(100);

synchronized(list) {

//还有鸡蛋时

while(list.size() >0) {

list.wait();

}

//没有鸡蛋时

while(list.size()==0){

Egg egg=newEgg();

egg.setId(count++);

egg.setName("鸡蛋");

System.out.println("生产线程生产"+egg.toString());

list.add(egg);

//通知消费线程

list.notify();

}

}

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}publicclassCustomerextendsThread {

privateList list;

publicCustomer(List list) {

this.list = list;

}

// 重写run方法

publicvoidrun() {

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[]) {

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();

}

}

}

}

Java代码  

//监控模型public class Control implements Runnable {

// 存放统计线程的队列

privatestaticList list =newArrayList();

// 主函数

publicstaticvoidmain(String args[]) {

// 取得系统的根目录个数

java.io.File[] dirF = java.io.File.listRoots();

// 根据目录创建统计纯种个数

for(inti =0; i

CountFile cf =newCountFile(dirF[i].getAbsolutePath());

cf.start();

list.add(cf);

}

System.out.println(dirF.length +" 个统计线程已启动");

// 启动监视线程

newThread(newControl()).start();

System.out.println("监视线程已启动");

}

// 实现run方法

publicvoidrun() {

booleanflag =true;

String result ="";

while(flag) {

for(inti =0; 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);

}

}publicclassCountFileextendsThread {

privateString root;// 进行搜索的根目录的名字

privateintlengthCount;// 所有文件长度

privateintdirCount;// 目录数

privateintrealFileCount;// 统计的真正文件数量

privatebooleanfinished =false;

// 构造时传入搜索根目录名

publicCountFile(String root) {

this.root = root;

}

/**

* 查看线程是否统计结束

*

* @return

*/

publicbooleanisFinished() {

returnfinished;

}

/**

* 返回统计结果

*

* @return

*/

publicString getResult() {

StringBuffer result =newStringBuffer();

result.append(root +"盘统计结果如下:\r\n");

result.append("  文件数量: "+ realFileCount);

result.append("   目录数: "+ dirCount);

result.append("   文件总长度(单位K): "+ lengthCount /1204);

result.append("\r\n");

returnresult.toString();

}

// 重写run方法

publicvoidrun() {

longstart = System.currentTimeMillis();

lengthCount = countProcess(root);

longcost = System.currentTimeMillis() - start;

finished =true;

}

/**

* 统计目录下文件的长度

*

* @param root

*            要统计的目录

* @return 目录下文件的长度

*/

privateintcountProcess(String root) {

intcount =0;

File dirFile =newFile(root);

// 目录不存在

if(!dirFile.exists()) {

returncount;

}

// 获得目录下的所有文件组成的数组

File[] subFile = dirFile.listFiles();

if(subFile ==null) {

returncount;

}

// 对这个数组进行遍历

for(inti =0; i

// 是个目录

if(subFile[i].isDirectory()) {

dirCount++;

count += countProcess(subFile[i].getAbsolutePath());// 用递归计算该目录下的文件长度

}

// 是一个文件

if(subFile[i].isFile()) {

realFileCount++;

count += subFile[i].length();

}

}

returncount;

}

}

//监控模型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;

}

}

java多线程基础_java线程基础相关推荐

  1. java多线程构造函数_java线程基础巩固---多线程与JVM内存结构的关系及Thread构造函数StackSize的理解...

    多线程与JVM内存结构的关系[了解]: 对于最后一个有疑问的构造中stackSize参数,其实学过编程滴人从参数字面就比较容易理解,栈大小嘛,这里从官方文档上来了解一下这个参数: 而之前在学习java ...

  2. java多线程抽奖_java 线程池、多线程并发实战(生产者消费者模型 1 vs 10) 附案例源码...

    导读 前二天写了一篇<Java 多线程并发编程>点我直达,放国庆,在家闲着没事,继续写剩下的东西,开干! 线程池 为什么要使用线程池 例如web服务器.数据库服务器.文件服务器或邮件服务器 ...

  3. java多线程示例_Java线程示例

    java多线程示例 Welcome to the Java Thread Example. Process and Thread are two basic units of execution. C ...

  4. java+向前进一_Java 线程基础

    前言 线程并发系列文章: 熟练掌握线程原理与使用是程序员进阶的必经之路,网上很多关于Java线程的知识,比如多线程之间变量的可见性.操作的原子性,进而扩展出的Volatile.锁(CAS/Synchr ...

  5. java多线程 门闩_Java线程与并发编程实践----同步器(倒计时门闩,同步屏障)...

    Java提供的synchronized关键字对临界区进行线程同步访问.由于基于synchronized很难 正确编写同步代码,并发工具类提供了高级的同步器.倒计时门闩(countdown latch) ...

  6. java线程抢占式执行,Java并发基础(一)-线程基础

    原标题:Java并发基础(一)-线程基础 只要涉及到线程,其运行结果就是不确定的,虽然说java很早就提供了线程以及并发的支持,但是我们需要知道,线程是完全交给调度器的.有很多同学在编写书上的代码时, ...

  7. Java多线程系列--“JUC线程池”06之 Callable和Future

    转载自  Java多线程系列--"JUC线程池"06之 Callable和Future Callable 和 Future 简介 Callable 和 Future 是比较有趣的一 ...

  8. Java多线程之守护线程实战

    转载自 Java多线程之<<守护线程>>实战 定义 什么是守护线程?与守护线程相对应的就是用户线程,守护线程就是守护用户线程,当用户线程全部执行完结束之后,守护线程才会跟着结束 ...

  9. java多线程面试_Java多线程和并发基础面试问答,看过后你不会后悔

    ***:Java多线程面试问题 1:进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java ...

最新文章

  1. python 图表_python导出excel charts图表
  2. Servlet(3):Cookie
  3. 基于Quartus II软件FPGA与PC之间的串行通信系统开发(9000+字)
  4. 30 天精通 RxJS (01):认识 RxJS
  5. java中s方法_Java中Arrys数组常用的方法
  6. SAP RFC 获取BDC 消息文本的实现
  7. 作者:袁书寒,男,同济大学博士生。
  8. fastreport dll_报表如何连接到VistaDB嵌入式数据库?FastReport.Net轻松搞定
  9. api 原生hbase_数据查询的玄铁剑:云HBase原生二级索引发布
  10. 鸿蒙系统受谷歌影响吗,华为鸿蒙系统,会受到人们的欢迎吗?
  11. Spring 三种bean装配的方式
  12. w3school入门自学免费网站推荐
  13. PHP 中跳转网页的三种方法
  14. ElasticSearch - 嵌套对象 nested
  15. 房产纠纷官司费用是多少
  16. Varnish 安装部署
  17. linux ftp 服务配置
  18. 【笔记】分布式网络与分布式账本
  19. Excel - 图文详解Excel中相对引用和绝对引用的区别
  20. 使用动态规划求解算法问题的五大特点总结(附基于Python的参考代码)

热门文章

  1. awk分割列-【AWK学习之旅】
  2. ThinkPHP导出CSV、Excel
  3. linux 查看磁盘空间大小命令
  4. MM32看门狗学习(兼容STM32)
  5. Apache ActiveMQ教程
  6. base64解密后乱码_php实现php代码的加密解密
  7. Android大学课件SQLite3 数据库操作
  8. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十九)ES6.2.2 安装Ik中文分词器
  9. [Tyvj模拟赛]运
  10. 北京联通光猫 F427 路由改桥接的方法