当前位置:首页 » 编程语言 » java执行线程

java执行线程

发布时间: 2022-06-19 11:34:54

java线程的作用什么

线程同步我们可以在计算机上运行各种计算机软件程序。每一个运行的程序可能包括多个独立运行的线程(Thread)。 线程(Thread)是一份独立运行的程序,有自己专用的运行栈。线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。

当多个线程同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团。

同步这个词是从英文synchronize(使同时发生)翻译过来的。我也不明白为什么要用这个很容易引起误解的词。既然大家都这么用,咱们也就只好这么将就。

线程同步的真实意思和字面意思恰好相反。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。

因此,关于线程同步,需要牢牢记住的第一点是:线程同步就是线程排队。同步就是排队。线程同步的目的就是避免线程“同步”执行。这可真是个无聊的绕口令。

关于线程同步,需要牢牢记住的第二点是 “共享”这两个字。只有共享资源的读写访问才需要同步。如果不是共享资源,那么就根本没有同步的必要。

关于线程同步,需要牢牢记住的第三点是,只有“变量”才需要同步访问。如果共享的资源是固定不变的,那么就相当于“常量”,线程同时读取常量也不需要同步。至少一个线程修改共享资源,这样的情况下,线程之间就需要同步。

关于线程同步,需要牢牢记住的第四点是:多个线程访问共享资源的代码有可能是同一份代码,也有可能是不同的代码;无论是否执行同一份代码,只要这些线程的代码访问同一份可变的共享资源,这些线程之间就需要同步。

为了加深理解,下面举几个例子
有两个采购员,他们的工作内容是相同的,都是遵循如下的步骤:
(1)到市场上去,寻找并购买有潜力的样品。
(2)回到公司,写报告。
这两个人的工作内容虽然一样,他们都需要购买样品,他们可能买到同样种类的样品,但是他们绝对不会购买到同一件样品,他们之间没有任何共享资源。所以,他们可以各自进行自己的工作,互不干扰。这两个采购员就相当于两个线程;两个采购员遵循相同的工作步骤,相当于这两个线程执行同一段代码。

下面给这两个采购员增加一个工作步骤。采购员需要根据公司的“布告栏”上面公布的信息,安排自己的工作计划。 这两个采购员有可能同时走到布告栏的前面,同时观看布告栏上的信息。这一点问题都没有。因为布告栏是只读的,这两个采购员谁都不会去修改布告栏上写的信息 下面增加一个角色。一个办公室行政人员这个时候,也走到了布告栏前面,准备修改布告栏上的信息。

如果行政人员先到达布告栏,并且正在修改布告栏的内容。两个采购员这个时候,恰好也到了。这两个采购员就必须等待行政人员完成修改之后,才能观看修改后的信息。

如果行政人员到达的时候,两个采购员已经在观看布告栏了。那么行政人员需要等待两个采购员把当前信息记录下来之后,才能够写上新的信息。

上述这两种情况,行政人员和采购员对布告栏的访问就需要进行同步。因为其中一个线程(行政人员)修改了共享资源(布告栏)。而且我们可以看到,行政人员的工作流程和采购员的工作流程(执行代码)完全不同,但是由于他们访问了同一份可变共享资源(布告栏),所以他们之间需要同步。

同步锁
前面讲了为什么要线程同步,下面我们就来看如何才能线程同步。
线程同步的基本实现思路还是比较容易理解的。我们可以给共享资源加一把锁,这把锁只有一把钥匙。哪个线程获取了这把钥匙,才有权利访问该共享资源。

生活中,我们也可能会遇到这样的例子。一些超市的外面提供了一些自动储物箱。每个储物箱都有一把锁,一把钥匙。人们可以使用那些带有钥匙的储物箱,把东西放到储物箱里面,把储物箱锁上,然后把钥匙拿走。这样,该储物箱就被锁住了,其他人不能再访问这个储物箱。(当然,真实的储物箱钥匙是可以被人拿走复制的,所以不要把贵重物品放在超市的储物箱里面。于是很多超市都采用了电子密码锁。)

线程同步锁这个模型看起来很直观。但是,还有一个严峻的问题没有解决,这个同步锁应该加在哪里? 当然是加在共享资源上了。反应快的读者一定会抢先回答。

没错,如果可能,我们当然尽量把同步锁加在共享资源上。一些比较完善的共享资源,比如,文件系统,数据库系统等,自身都提供了比较完善的同步锁机制。我们不用另外给这些资源加锁,这些资源自己就有锁。

但是,大部分情况下,我们在代码中访问的共享资源都是比较简单的共享对象。这些对象里面没有地方让我们加锁。

读者可能会提出建议:为什么不在每一个对象内部都增加一个新的区域,专门用来加锁呢?这种设计理论上当然也是可行的。问题在于,线程同步的情况并不是很普遍。如果因为这小概率事件,在所有对象内部都开辟一块锁空间,将会带来极大的空间浪费。得不偿失。

于是,现代的编程语言的设计思路都是把同步锁加在代码段上。确切的说,是把同步锁加在“访问共享资源的代码段”上。这一点一定要记住,同步锁是加在代码段上的。

同步锁加在代码段上,就很好地解决了上述的空间浪费问题。但是却增加了模型的复杂度,也增加了我们的理解难度。

❷ java 执行线程的方法是( )

先是start启动线程,真正执行是run()

❸ Java中,线程是什么意思,多线程又是什么

在计算机中当一个程序运行的时候就会创建至少一个进程,例如当我们运行QQ的时候,系统就会创建进程来处理我们平时的一些操作,当我们打开任务管理器的时候,在进程的列表里面就可以找到QQ.exe的运行程序;

在计算机中处理进程之外还有另一个概念就是线程,线程是存在于进程当中,一个进程可以包含多个线程;当我们的计算机有多核处理器的时候,使用多线程可以加快程序的运算速率;如果一个进程中只有一个线程,当程序遇到一个比较耗时的计算的时候,由于程序是单线程的,那么程序只能等待这个运算结束的时候再继续运行,这样会大大的降低程序的效率;当时用多个线程的时候,在某个线程遇到比较耗时的运算的时候,该线程可以继续自己的运算,但是其他的线程也可以同步进行,这样当耗时的计算结束之后,其他线程也将自己所需要的东西执行完毕,这样就会很大的提高程序执行效率;

在程序运行中对于文件的保存相对于处理器的运算速度来说是很慢的,当我们程序中接收到一个保存文件的信息之后,我们可以创建一个保存文件的线程,在主线程中我们可以继续进行我们的其他运算,这样当文件保存好之后,我们的其他运算也会完成,互不影响;

在Java中我们可以创建一个自己的类继承于Thread类,并且重写run() 方法,当线程启动之后,run()方法里面的操作都在线程中进行处理,而不会影响主线程的信息;

当我们创建好一个自定义线程类之后,我们可以创建这个自定义线程的对象,进行线程的启动;线程须调用start();方法进行启动,这样run()方法里面的内容才会在线程中运行;如果我们不去调用start()方法,那我们只是创建了一个普通的类,即使我们手动调用run()方法,run()方法里面的内容也不会在线程中运行;

在Java中线程主要有初始状态,运行状态,阻塞状态,终止状态等;当我们新创建一个线程对象的时候,此时线程的状态为初始状态;当我们调用start()之后,此时的线程才被激活成为运行状态,之后run()方法里面的信息才会在子线程中运行;我们可以在不同的阶段调用不同的方法将线程设置为不同的状态;比如有时候我们的操作需要等待其他线程中运算结束之后才可以继续进行,这时候我们就可以将线程设置为等待状态,当需要的资源满足条件之后,可以继续运行当前的线程;

以上的内容就是关于Java中线程是什么,更多关于Java方面的问题可以看下这个视频教程:网页链接,希望我的回答能帮到你。

❹ 如何创建并运行Java线程

Java线程类也是一个object类,它的实例都继承自java.lang.Thread或其子类。 可以用如下方式用java中创建一个线程:

Tread thread = new Thread();

执行该线程可以调用该线程的start()方法:

thread.start();

在上面的例子中,我们并没有为线程编写运行代码,因此调用该方法后线程就终止了。

编写线程运行时执行的代码有两种方式:一种是创建Thread子类的一个实例并重写run方法,第二种是创建类的时候实现Runnable接口。接下来我们会具体讲解这两种方法:

创建Thread的子类

创建Thread子类的一个实例并重写run方法,run方法会在调用start()方法之后被执行。例子如下:

public class MyThread extends Thread {
public void run(){
System.out.println("MyThread running");
}
}

可以用如下方式创建并运行上述Thread子类

MyThread myThread = new MyThread();
myTread.start();

一旦线程启动后start方法就会立即返回,而不会等待到run方法执行完毕才返回。就好像run方法是在另外一个cpu上执行一样。当run方法执行后,将会打印出字符串MyThread running。

你也可以如下创建一个Thread的匿名子类:

Thread thread = new Thread(){
public void run(){
System.out.println("Thread Running");
}
};
thread.start();

当新的线程的run方法执行以后,计算机将会打印出字符串”Thread Running”。

实现Runnable接口

第二种编写线程执行代码的方式是新建一个实现了java.lang.Runnable接口的类的实例,实例中的方法可以被线程调用。下面给出例子:

public class MyRunnable implements Runnable {
public void run(){
System.out.println("MyRunnable running");
}
}

为了使线程能够执行run()方法,需要在Thread类的构造函数中传入 MyRunnable的实例对象。示例如下:

Thread thread = new Thread(new MyRunnable());
thread.start();

当线程运行时,它将会调用实现了Runnable接口的run方法。上例中将会打印出”MyRunnable running”。

同样,也可以创建一个实现了Runnable接口的匿名类,如下所示:

Runnable myRunnable = new Runnable(){
public void run(){
System.out.println("Runnable running");
}
}
Thread thread = new Thread(myRunnable);
thread.start();

创建子类还是实现Runnable接口?

对于这两种方式哪种好并没有一个确定的答案,它们都能满足要求。就我个人意见,我更倾向于实现Runnable接口这种方法。因为线程池可以有效的管理实现了Runnable接口的线程,如果线程池满了,新的线程就会排队等候执行,直到线程池空闲出来为止。而如果线程是通过实现Thread子类实现的,这将会复杂一些。

有时我们要同时融合实现Runnable接口和Thread子类两种方式。例如,实现了Thread子类的实例可以执行多个实现了Runnable接口的线程。一个典型的应用就是线程池。

常见错误:调用run()方法而非start()方法

创建并运行一个线程所犯的常见错误是调用线程的run()方法而非start()方法,如下所示:

Thread newThread = new Thread(MyRunnable());
newThread.run(); //should be start();

起初你并不会感觉到有什么不妥,因为run()方法的确如你所愿的被调用了。但是,事实上,run()方法并非是由刚创建的新线程所执行的,而是被创建新线程的当前线程所执行了。也就是被执行上面两行代码的线程所执行的。想要让创建的新线程执行run()方法,必须调用新线程的start方法。

线程名

当创建一个线程的时候,可以给线程起一个名字。它有助于我们区分不同的线程。例如:如果有多个线程写入System.out,我们就能够通过线程名容易的找出是哪个线程正在输出。例子如下:

MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable, "New Thread");
thread.start();
System.out.println(thread.getName());

需要注意的是,因为MyRunnable并非Thread的子类,所以MyRunnable类并没有getName()方法。可以通过以下方式得到当前线程的引用:

Thread.currentThread();

因此,通过如下代码可以得到当前线程的名字:

String threadName = Thread.currentThread().getName();

线程代码举例:

这里是一个小小的例子。首先输出执行main()方法线程名字。这个线程JVM分配的。然后开启10个线程,命名为1~10。每个线程输出自己的名字后就退出。

public class ThreadExample {
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
for(int i=0; i<10; i++){
new Thread("" + i){
public void run(){
System.out.println("Thread: " + getName() + "running");
}
}.start();
}
}
}

需要注意的是,尽管启动线程的顺序是有序的,但是执行的顺序并非是有序的。也就是说,1号线程并不一定是第一个将自己名字输出到控制台的线程。这是因为线程是并行执行而非顺序的。Jvm和操作系统一起决定了线程的执行顺序,他和线程的启动顺序并非一定是一致的。

❺ Java中某一特定线程的具体任务在哪个方法中执行

这个程序的执行顺序不不一定的,它的执行顺序还跟线程分的时间片有关
CPU运算的时间 是分时间片 分给不同的线程的 一个线程执行完 或者用完了当前它分到的那个时间片 他就得让出CPU给其他线程使用啦!
线程化是允许多个活动共存于一个进程中的工具。大多数现代的操作系统都支持线程,而且线程的概念以各种形式已存在了好多年。Java 是第一个在语言本身中显式地包含线程的主流编程语言,它没有把线程化看作是底层操作系统的工具。
有时候,线程也称作轻量级进程。就象进程一样,线程在程序中是独立的、并发的执行路径,每个线程有它自己的堆栈、自己的程序计数器和自己的局部变量。但是,与分隔的进程相比,进程中的线程之间的隔离程度要小。它们共享内存、文件句柄和其它每个进程应有的状态。
进程可以支持多个线程,它们看似同时执行,但互相之间并不同步。一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,而且它们从同一堆中分配对象。尽管这让线程之间共享信息变得更容易,但您必须小心,确保它们不会妨碍同一进程里的其它线程。
Java 线程工具和 API 看似简单。但是,编写有效使用线程的复杂程序并不十分容易。因为有多个线程共存在相同的内存空间中并共享相同的变量,所以您必须小心,确保您的线程不会互相干扰。
每个 Java 程序都使用线程
每个 Java 程序都至少有一个线程 ― 主线程。当一个 Java 程序启动时,JVM 会创建主线程,并在该线程中调用程序的 main() 方法。
JVM 还创建了其它线程,您通常都看不到它们 ― 例如,与垃圾收集、对象终止和其它 JVM 内务处理任务相关的线程。其它工具也创建线程,如 AWT(抽象窗口工具箱(Abstract Windowing Toolkit))或 Swing UI 工具箱、servlet 容器、应用程序服务器和 RMI(远程方法调用(Remote Method Invocation))。

❻ 如何创建并运行java线程

1
2
3
4
5
6
7
8
9
10
11

创建线程,就是这样
extends Thread 或者 implements Runnable,但是有很多问题;

所以引申出了下面的线程池
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,
若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,
保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

❼ java线程执行完后自己结束吗

其实最佳答案的说法是有问题的,如果题主指的结束,是指方法块语句的执行结束的话,热心网友的说法是对的。但是对于线程本身,所有线程(包括主线程)在启动后都被CPU参照优先级交替调用,运行的顺序是无法预测的,但最后结束的一定是主线程。
网上有部分说法,展示的代码运行结果,“主线程先于其他线程结束,并不影响其他线程的运行”只有后半部分是对的。因为方法体(不管是自定义线程的run()还是主线程的main())中全部语句的执行完毕不代表所在线程的结束,可以用activeCount()返回当前运行的总线程数来验证这一点。另外,如果将自定义的线程对象设定为守护线程(setDeamon()),也可以很清楚看到即便main()方法中最后一句输出语句执行完毕,控制台仍会根据该自定义线程run()方法体的内容继续输出,这证明主线程还没结束——因为当线程组中只剩下守护线程时,JVM虚拟机会自动退出,如果主线程已经结束,唯一活动的线程在被设置成守护线程的情况下,程序会直接结束运行,不可能继续输出。

❽ 请问java中多线程的执行顺序是怎样的

thread类是被继承的,执行的时候调用的是继承它的子类,但java一般实现多线程不是继承thread类,而是实现runnable接口,因为java不能多重继承,所以继承thread类后就不能继承别的类了。
只要实现runnable接口(或继承了thread类)就可以实现多线程。
比如说有a
b
c
d
e五个类都实现runnable接口(或继承了thread类)
你先进了main方法,就创建了一个线程,这个线程是main方法的
你调用a的run()方法,就又创建一个线程,这个线程是a方法的。
如果还不懂得话建议你去看看什么叫继承和接口,基础差的话理解起来有点困难
我可是辛辛苦苦打字半天了~~~

❾ java 线程池是怎么处理执行线程的

java中线程池的监控可以检测到正在执行的线程数。
通过线程池提供的参数进行监控。线程池里有一些属性在监控线程池的时候可以使用
taskCount:线程池需要执行的任务数量。
completedTaskCount:线程池在运行过程中已完成的任务数量。小于或等于taskCount。
largestPoolSize:线程池曾经创建过的最大线程数量。通过这个数据可以知道线程池是否满过。如等于线程池的最大大小,则表示线程池曾经满了。
getPoolSize:线程池的线程数量。如果线程池不销毁的话,池里的线程不会自动销毁,所以这个大小只增不+ getActiveCount:获取活动的线程数。
通过扩展线程池进行监控。通过继承线程池并重写线程池的beforeExecute,afterExecute和terminated方法,我们可以在任务执行前,执行后和线程池关闭前干一些事情。如监控任务的平均执行时间,最大执行时间和最小执行时间等。这几个方法在线程池里是空方法。

❿ java中多线程程序是怎样执行的

Thread.start()只是代表启动了一个线程,什么时候执行这要依赖于操作系统对CPU时间片的分配,另外启动一个线程是需要资源的,所以肯定会存在延迟,为什么会执行“测试二”,搞清楚,这里已经是两个线程了,一个线程是t,另外一个线程是主线程,也就是创建NewThread的线程。所以,t怎么会阻碍主线程的运行呢?

热点内容
华为平板怎么储存服务器文件 发布:2025-02-06 12:49:21 浏览:481
php查询结果数组 发布:2025-02-06 12:31:05 浏览:716
怎样把照片压缩打包 发布:2025-02-06 12:15:19 浏览:498
如何编译java文件 发布:2025-02-06 12:05:58 浏览:237
九九乘法编程 发布:2025-02-06 12:05:05 浏览:519
台式机忘记开机密码怎么办 发布:2025-02-06 11:58:01 浏览:871
android刷新按钮 发布:2025-02-06 11:57:17 浏览:586
存储过程有输入参数和输出参数 发布:2025-02-06 11:55:32 浏览:99
成绩评选算法 发布:2025-02-06 11:42:51 浏览:997
数据库测试数据 发布:2025-02-06 11:31:05 浏览:824