因为昨天看一则关于Synchronized(线程安全的帖子),只是觉得有些奇
怪,其实当你明白一些基础后,你完全就可以自学Java了,但是OO的思想是要通过大量的实例以及实践形成的。(其实我的OO思想也不是很强烈,也正如
neo_q牛人所说:"简单地说继承、封装、多态,在我们的程序中都应该是要能体现出来的")。
我在看线程的时候,并没觉得有多么困难,也可能是我学的根本就不深入。下面进入正题:
线程简介:
谈到线程,就必然要提到另一个概念,那就是进程。一般可以在同一时间内执行多个程
序的操作系统都有进程的概念。一个进程就是一个执行中的程序,而每一个进程都有自己独立的一块内存空间、一组系统资源。在进程概念中,每一个进程的内部数
据和状态都是完全独立的。Java通过流控制来执行程序流,程序中单个顺序的流控制称为线程,多线程则意味着一个程序的多行语句可以几乎
在同一时间内同时运行。(为什么是几乎,不是同时,涉及到计算机原理,暂不多讲)
线程与进程相似,是一段完成某个特定功能的代码,是程序中单个顺序的流控制;但与
进程不同的是,同类的多线程是共享一块内存空间和一组系统资源,而线程本身的数据通常只有CPU的寄存器数据,以及一个供程序执行时使用的堆栈。所以系统
在产生一个线程,或者在各个线程之间切换时,负担要比进程小的多,所以线程可以被看作是轻量级的进程。一个进程中可以包含多个线程,一个线程是一个程序内
部的顺序控制流。
作为Java的一个重要的特性,Java内在支持多线程,它的所有类都是在多线程下定义的、Java利用多线程使整个系统成为异步系统。Java中的线程由3个部分组成:虚拟的CPU、CPU所执行的代码和CPU所处理的数据。
线程体的概念:
虚拟的CPU被封装在java.lang.Thread类中,这样CPU所执行的
代码和CPU所处理的数据都传递给java.lang.Thread类的实例中。所以Java的线程是通过java.lang.Thread类来实现的。
当我们生成一个Thread
类的对象后,一个新线程就产生了。现成实例表示Java解释器中的真正的线程,通过它可以启动线程、终止线程、线程挂起等。每个线程都是通过某个特定
Thread对象的方法run()来完成其操作的,方法run()称为线程体。
Thread类有8个构造函数:
略……API中明确写出
Thread类的常用方法:(新手常用)
static Thread currentThread() //静态方法,通过这个方法可以获得主线程的引用,从而达到操作主线程的目的。(什么是主线程?参见主线程)
static int activeCount() //静态方法,获得当前活动线程数量
long getId() //获得当前线程id
String getName() //获得当前线程名字
int getPriority() //获得优先级
boolean isAlive() //当前线程是否处于活动状态。
boolean isDaemon()//是否为守护线程
void run()//run()方法,我们用线程,主要就是对run()方法的重写
void start() // 使该线程开始执行;Java 虚拟机调用该线程的run() 方法。
void sleep() //使当前线程休眠,以执行其他线程,如Thread.sleep(1000) 休眠1秒
其实这些方法API中都有,而且写的都很详细,就不多说了。
线程体的自定义:
Java 中使用线程无非就是对run()方法的重写,你可以通过继承Thread类或者使用Runnable接口来定义你自己的线程。由于Java的单一继承,所以提供了Runable接口。
=======================================================================
写几个简单的例子:
class MyThread extends Thread{//继承Thread实现线程,但是此类将不能再继承别类。
public myThread(String name){
super(name);
}//这是myThread的构造方法,将name传给Thread,name即自定义线程名字
public void run(){
System.out.println("This is myThread :"+this.getName());
for(int i=0;i<10;i++)
System.out.println("This is myThread :"+this.getName()+" : "+i);
}//run()方法的重写
}
public class ThreadDemo{
public static void main(String [] args){
MyThread mt = new MyThread("线程1"); //实例化线程1,下文引用的①
MyThread mt1 = new MyThread("线程2");//实例化线程2
mt.start();//线程1运行,下文引用的②
mt1.start();//线程2运行
}
}
=====================================================================
class MyThread implements Runnable{ //接口实现线程
private Thread myThread = null;
public myThread(String name){
super();
this.myThread = new Thread(this,name);
}//这是myThread的构造方法。
public void start(){
myThread.start();
}//由于接口Runnable中,只有一个抽象run()方法,所以我们要定义一个start()方法,使当前线程运行。
public void run(){
System.out.println("This is myThread :"+this.getName());
for(int i=0;i<10;i++)
System.out.println("This is myThread :"+this.getName()+" : "+i);
}//run()方法的重写
}
//main()方法基本一样,就不写了,由于以上代码都是在这里写的,在baidu blog中tab不好使,所以……丑
//这里我主要想说明的是线程的两种实现方式,一是继承Thread,二使用Runnable接口。
==========================================================================
线程的状态:
线程的状态有4种:创建状态、可执行状态、不可执行状态、死亡状态。
创建状态:实例化线程对象后,线程就处于创建状态,此时系统不为它分配资源。接上文①位置。
可执行状态:当调用了run()方法后,线程就处于可运行状态,系统为他分配了它需要的系统资源。这里要注意可运行与运行之分,调用了run()方法,并不代表它正在运行,同一时刻只能运行处于可运行状态的的线程中的一个。
不可运行状态:不可运行状态也称为组塞状态,由于某中圆心系统不能执行线程的状
态。在这种情况下,即便CPU空闲,线程也不能被执行。线程成为不可能运行状态可能因为:Ⅰ.调用了sleep()方法。Ⅱ.调用了suspend()方
法。Ⅲ.调用了wait()方法。Ⅳ.输入输出流中发生线程阻塞。
死亡状态:线程执行完会自动进入死亡状态或是调用了stop()方法都会进入死亡状态。stop()方法已经过时。
主线程:
Java程序启动运行时JVM会自动创建一个现成,这个就是主线程。
主线程的重要性和特殊性表现在下面两个方面:
1。他是产生其他线程的线程。
2。它通常执行各种关闭操作,是最后结束的。
在这里你可以理解main()为一个主线程。只有main()的产生,你才可以new出新的myThread线程对象。
线程调度:
在没有设置优先级的情况下,Java提供了一个线程调度器来调度程序启动后进入可运行状态的所有线程。线程调度器按线程的优先级高低选择优先级高的先执行。
线程调度是抢先式调度,即当前线程执行过程中,一个更高级的线程进入可运行状态,将暂停原线程的运行,去执行更高级的线程。
抢先式调度又分为:时间片方式和独占方式。时间片方式可以理解为按一定时间执行各
个处于可运行状态的线程,当时间到时,不管是否执行完,都转入对下一个线程的执行。独占方式则是指CPU始终在执行一个线程,只有当前线程执行完后或线程
主动退出后,才转入对下一个线程的执行。
线程优先级:
Java中线程有10个优先级,由低到高分别用1~10表示。Thread类中定义了3个静态变量,分别是Thread.MIN_PRIORITY 代表最低优先级1,Thread.NORM_PRIORITY 普通5,Thread.MAX_PRIORITY 最高10
我们可以通过setPriority(),以及getPriority()对当前线程优先级进行操作。
假如有myThread0,myThread1,以及myThread2、三个线程同时处于可运行状态,分别对应min、norm、max优先级,那CPU将会先执行优先级为max、再执行norm、最后执行min的run()方法。
守护线程:(精灵线程)
线程默认都是非守护线程,非守护线程也称做用户线程。程序中当所有用户线程都结束时,守护线程也立即结束。因为守护现成随时会结束,所以守护线程所做的工作应该是可以随后结束而不应该运行结果的工作。
我们通过setDaemon(boolean on)来设置当前线程是否为守护线程。还是上面的继承Thread的例子,我们再多写一个MyThread2,其中run()方法为
while(true)
System.out.println("This is Daemon Thread");
并且在main()中这样写
MyThread2 mtDaemon = new MyThread2("DaemonThread");
mtDaemon.start();
mtDaemon.setDaemon(true);
假如没有setDaemon()这句,mtDaemon线程将进入死循环,并导致正个程序都不能停止,而如果设置了setDaemon()后当mt线程进入死亡状态后,main()也结束时,mtDaemon也伴随结束。一般守护线程可以用于程序的自动更新什么的。
线程同步:(线程安全)
当有多个线程共享一个变量时,需要确保资源在某一个时刻只有一个线程占用,这个过程就是线程同步。
举例说明:假如有3个人同时在拨打同1个电话号码,这3个人好比3个可运行状态的线程,都在拨打的电话号码就是共享变量。而当前电话不可能被3个人同时拨通,只有第1个被接通人的电话挂断,其他2个人的1个才能被接进来,第2个人再挂断电话,第3个人才能接近来。
这里主要用到的就是synchronized关键字。我这里有一个例子:
============================================================================
class PhoneCalls{
private String phoneName = "";
public PhoneCalls(String name) {
this.phoneName = name;
}
public void call(String name){
try{
System.out.println("<---"+name+"拨打"+this.phoneName+"电话--->");
Thread.sleep(1000);
System.out.println("<---"+name+"正在通话ing--->");
Thread.sleep(1000);
System.out.println("<---"+name+"挂断电话--->");
}catch(Exception e){
e.printStackTrace();
}
}
}
public class SynCalls implements Runnable{
private String name = "";
private PhoneCalls phone = null;
private Thread thread = null;
public SynCalls(String name,PhoneCalls phone) {
this.name = name;
this.phone = phone;
this.thread = new Thread(this);
}
public void start(){
this.thread.start();
}
public void run() {
synchronized (this.phone) {
this.phone.call(this.name);
}
}
public static void main(String [] args){
PhoneCalls phone = new PhoneCalls("狗剩的电话");
SynCalls frist = new SynCalls("张三",phone);
SynCalls second = new SynCalls("李四",phone);
SynCalls third = new SynCalls("王五",phone);
frist.start();
second.start();
third.start();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
另外本文概念部分并非我写,我还没那么牛PP能那么厉害。这是我从书中体会来的加自己的见解合成的东西。
其实个人的拓展是非常重要的,经常看API以及tutorial(这个东西不错,里面带很多例子),或者一些其他书籍会很有帮助学习Java。
下面我还想引用neo_q大叔的一些话,虽然不是对我讲的,但是对于初学者应该看一看。
你的程序目前功
能都是可以实现的,但是面向对象的思想几乎是没有体现在你的代码中,简单地说继承、封装、多态,在我们的程序中都应该是要能体现出来的,因为我并不知道你
开始使用java编程有多久了,但是就我从你的代码成熟度来看,应该不会超过一年,如果你已经超过一年,那么你要好好反思一下。有两个建议,还有几本书推
荐给你。
1.进一步巩固java基础。thinking in
java必须看完,而且是一字不差地读完,所有讲到的知识点都要写testcase,而且这本书最大的好处是在你不知不觉中培养你的OO思想,对你应该有
所帮助,这本书至少读两遍,视你的情况而定如果第二遍不能全部理解,那么再来一轮直到真的全部理解,之后你可以看看effective in
java,为什么你到时候我相信会明白的。
2.逐步从写出代码到写好代码过渡。这个不是一蹴而就的,一定要在写的过程中慢慢培养一种思考方式和编程的习惯,那是什么样的习惯呢?重构的习惯,至于重
构是怎么会事情,简单说就是写完了重写一遍,你千万别觉得这个是麻烦事情,他的帮助是很大的,会告诉你如果下次遇到这样的情况,那么你就会按照好的那种方
法来写。至于如何做到有两本书可以帮助你,Martin Fowler写的《重构》,Steve
McConnell《代码大全》第二版。看完这两本书,你会再上一个层次。
接下来还有很长的路,希望对你有所帮助,如果你觉得我这是废话,那么请完全忽略。:)
另外一句话,swing的东西还是少做点,尽快转向J2EE吧,毕竟外面的企业中还是J2EE较多,但是如果你真的喜欢做桌面的话,或者兴趣在此,那么当我没说。
分享到:
相关推荐
本书的新版本展示了如何利用Java线程工具的全部优势,并介绍了JDK 2线程接口中的最新变化。你将学习如何使用线程来提高效率,如何有效地使用它们,以及如何避免常见的错误。本书讨论了死锁、竞态条件以及饥饿等问题...
### Java线程使用教程知识点详解 #### 一、线程基础概述 - **定义与特点**:线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。Java是首个在语言级别明确支持线程特性的...
本示例"简单的Java线程demo"旨在帮助初学者理解如何在Java中创建和管理线程。 在Java中,有两种主要的方式来创建线程:继承Thread类和实现Runnable接口。下面我们将详细讨论这两个方法。 1. 继承Thread类: 当一个...
### JAVA中的单线程与多线程概念解析 #### 单线程的理解 在Java编程环境中,单线程指的是程序执行过程中只有一个线程在运行。这意味着任何时刻只能执行一个任务,上一个任务完成后才会进行下一个任务。单线程模型...
为了在多线程中同步进度更新,我们可以利用synchronized关键字、wait()、notify()方法,或者使用Java并发库中的高级工具,如Semaphore、CyclicBarrier或CountDownLatch等。 一个简单的进度条实现可以采用共享变量...
在Java出现以前,似乎人人都在谈论线程,却很少有人使用它。用线程编程是技巧性很强的且不可移植。 而在Java中却完全不同。Java的线程工具易于使用,并且像Java中的其他东西一样可以在不同的平台之间移植。这是一件...
【Java多线程简单下载器】是一个初学者的编程作业,虽然代码可能较为混乱,但其核心功能已经实现,即通过多线程技术进行文件的下载。在Java中,多线程是并发处理的重要手段,它允许多个任务在同一时间执行,从而提高...
java Runnable线程简单实例。简单实用,可用可参考;多用多理解;线程可用用在很多场景,java程序猿必备技能
总结起来,Java线程涉及的内容广泛,包括线程的创建、控制、同步以及线程池的使用。理解这些知识点对于编写高效、安全的多线程Java应用程序至关重要。在实践中,合理地利用线程和同步机制,能有效提升程序的性能,...
用反射实现了对java线程简单的封装,类似c#线程,使用此封装类勿需再次继承Thread类或实现Runnable接口,直接绑定需要使用线程的方法即可,另支持动态传参,如觉着好用请多多支持作者 QQ 359103820 希望能为使用线程...
综上所述,这个“java 多线程简易聊天 精简版”项目涵盖了Java多线程编程的诸多核心概念,包括线程创建、网络通信、同步与互斥、异常处理以及IDE的使用。对于希望深入学习Java多线程编程的开发者来说,这是一个很好...
Java线程机制是Java编程语言中的一个重要特性,它使得开发者能够在...理解和熟练使用Java线程机制对于任何Java开发者来说都是至关重要的,无论是优化性能、提高响应性还是实现复杂的并发模式,都能发挥其巨大的作用。
简单的java线程代码 对Thread中的sleep方法进行测试
本书的新版本展示了如何利用Java线程工具的全部优势,并介绍了JDK 2线程接口中的最新变化。你将学习如何使用线程来提高效率,如何有效地使用它们,以及如何避免常见的错误。本书讨论了死锁、竞态条件以及饥饿等问题...
在实际开发中,使用Java多线程技术时,开发者可能会面临一些挑战,比如线程安全问题、死锁问题、资源竞争和线程饥饿等。线程安全是指多个线程对共享资源进行访问时,不会导致数据不一致或者程序行为异常。Java虚拟机...
《Java线程书》作为一本面向初学者的教程,旨在帮助读者理解线程的基本概念,并掌握如何在Java程序中使用线程。 #### 二、线程基础概念 ##### 1. 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被...
《Java线程 高清晰中文第二版》中文第二版(PDF) 前言 第一章 线程简介 Java术语 线程概述 为什么要使用线程? 总结 第二章 Java线程API 通过Thread类创建线程 使用Runable接口的线程 线程的生命周期 线程命名 ...
#### 一、Java线程:概念与原理 1. **操作系统中线程和进程的概念** - 当前的操作系统通常为多任务操作系统,多线程是实现多任务的一种手段。 - **进程**:指内存中运行的应用程序,每个进程拥有独立的内存空间。...
Java线程是多任务编程的核心概念,特别是在大型的、复杂的软件系统中,如Eclipse这样的集成开发环境(IDE)中的项目。在这个"Eclipse项目java线程实例"中,我们可以深入理解并实践Java线程的创建、管理和同步机制。 ...