齐头并进完成任务——Java多线程(一)
多线程(Multithread)指的是在单个进程中同时运行多个不同的线程,执行不同的任务。多线程意味着一个程序的多行语句块并发执行。
一、实现多线程
1.通过继承Thread类实现多线程。
Thread类来自java.lang包,在Thread类中定义了run()方法,想要实现多线程,必须覆写run()方法。然后使用该类的对象调用start()方法,来激活一个线程。
class ThreadDemo extends Thread
{
public void run()
{
for(int i=0;i<2;++i)
{
System.out.println("ThreadDemo在运行!");
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
} public class ThreadTest
{
public static void main(String[] args)
{
new ThreadDemo().start();//激活一个新的线程
for(int j=0;j<2;++j)
{
System.out.println("main方法在运行!");
try
{
Thread.sleep(1000);//睡眠1s
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
输出结果:
main方法在运行!
ThreadDemo在运行!
main方法在运行!
ThreadDemo在运行!
上述例子中的InterruptedException,表示中断异常类,Thread.sleep()和Object.wait()都可以抛出这类中断异常,printStackTrace()方法输出异常信息,这样就可以很清楚的看到两个线程交替执行的结果。如果去掉异常处理语句,那么运行结果如下:
main方法在运行!
main方法在运行!
ThreadDemo在运行!
ThreadDemo在运行!
这个运行结果貌似不是多线程并发执行,但事实上因为循环次数过少,线程运行并没有超过时间片t,所以先把main方法执行的主线程的for循环执行完毕,再转去执行ThreadDemod的线程。(具体的会在第二部分线程的状态中叙述)
2.通过Runnable接口实现多线程。
因为接口可以实现多继承的原因,Runnable接口实现多线程机制更加常用。
class RunnableDemo implements Runnable
{
public void run()
{
for(int i=0;i<2;++i)
{
System.out.println("RunnableDemo在运行!");
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
} public class ThreadTest
{
public static void main(String[] args)
{
RunnableDemo r = new RunnableDemo();
new Thread(r).start();//使用Thread类的start()方法启动线程
for(int i=0;i<2;++i)
{
System.out.println("main方法在运行!");
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
值得一提的是,Runnable接口中只有一个run()方法,所以激活一个新线程仍然使用Thread类的start()方法。
new Thread(r).start();Thread类的构造方法,可以将一个Runnable接口(及其子类)的实例化对象作为参数去实例化Thread类对象。
3.两种多线程实现机制的联系与区别
联系:Thread类实现Runnable接口,即Thread类是Runnable的一个子类。
区别:Thread类很难实现资源共享,每个Thread实例都是在独自运行自己的线程,但能通过静态变量实现资源共享;Runnable接口可以直接达到资源共享的目的。
***注意:事实上,上述两个示例程序的运行结果都不唯一,这个错误就是和线程运行的时间片和相关临界区有关。
二、线程的状态
每个Java程序都有一个默认的主线程,对于Java应用程序,主线程是main方法执行的线程。要想实现多线程,必须在主线程中创建新的线程对象。
1.线程具有5种状态:创建、就绪、运行、阻塞、终止。关系如下图:

创建:ThreadDemo t = new ThreadDemo();
就绪:t.start();
运行:执行run()方法。
阻塞:暂时停止执行,原因可能是:调用sleep()、调用wait()、发生I/O阻塞、调用join()方法、不能获得对象锁。
终止:线程执行完毕。
2.线程的优先级
Thread类定义的常量来设置优先级:MAX_PRIORITY(10)、NORM_PRIORITY(5)、MIN_PRIORITY(1)。
三、操作线程的方法
操作线程的主要方法在Thread类中,下面介绍一些常用的方法:
1.getName()和setName()取得和设置线程名称
Thread t = Thread.currentThread();//静态方法,返回当前正在运行的线程
String name = t.getName();//取得线程的名称
t.setName("线程2—1");//设置线程的名称
2.isAlive()方法——判断线程是否启动
ThreadDemo t = new ThreadDemo();
Boolean b = t.isAlive();//true或false
3.setDaemon()方法——转变为守护线程
ThreadDemo t = new ThreadDemo();
t.setDaemon(true);//设置守护线程,必须在start()方法前面
t.start();
当进程中只剩下守护线程的时候,进程才会结束。
4.join()方法——线程联合
try {
t.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
a线程正在运行——b.join();——a线程挂起,b线程强制运行——b线程运行结束——a线程继续运行。
5.interrupt()方法——线程中断
isInterrupt()方法——判断线程是否处于中断状态
t.interrupt();
Boolean b = t.isInterrupted();
当一个线程运行时,另一个线程可以调用另外一个线程对应的interrupt()方法来中断它。
***注意:调用interrupt()方法并不会使正在执行的线程停止执行,它只对调用wait、join、sleep等方法或由于I/O操作等原因受阻的线程产生影响,使其退出暂停执行的状态。
即:interrupt()对正在运行的线程是不起作用的,只有对阻塞的线程有效。
齐头并进完成任务——Java多线程(一)的更多相关文章
- java多线程系类:JUC线程池:02之线程池原理(一)
在上一章"Java多线程系列--"JUC线程池"01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我 ...
- Java—多线程编程
一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程.一个线程不能独立的存 ...
- Java多线程简析
一.线程的状态: 线程共有下面4种状态: 1.新建状态(New): 新创建了一个线程对象,当你用new创建一个线程时,该线程尚未运行. 2.就绪状态(Runnable): 线程对象创建后,其他线程调用 ...
- JAVA多线程 问题 转载
参考:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/ http://www.cn ...
- Java多线程20:多线程下的其他组件之CountDownLatch、Semaphore、Exchanger
前言 在多线程环境下,JDK给开发者提供了许多的组件供用户使用(主要在java.util.concurrent下),使得用户不需要再去关心在具体场景下要如何写出同时兼顾线程安全性与高效率的代码.之前讲 ...
- Java多线程系列--“JUC线程池”02之 线程池原理(一)
概要 在上一章"Java多线程系列--“JUC线程池”01之 线程池架构"中,我们了解了线程池的架构.线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析Th ...
- JAVA多线程基础知识(一)
一. 基础知识 要了解多线程首先要知道一些必要的概念,如进程,线程等等.开发多线程的程序有利于充分的利用系统资源(CPU资源),使你的程序执行的更快,响应更及时. 1. 进程,一般是指程序或者任务的执 ...
- 【Java多线程】两种基本实现框架
Java多线程学习1——两种基本实现框架 一.前言 当一个Java程序启动的时候,一个线程就立刻启动,改程序通常也被我们称作程序的主线程.其他所有的子线程都是由主线程产生的.主线程是程序开始就执行的, ...
- 【转】 Java 多线程之一
转自 Java 多线程 并发编程 一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进 ...
随机推荐
- LeetCode Weekly Contest 28
1. 551. Student Attendance Record I 2. 552. Student Attendance Record II hihocode原题,https://hihocode ...
- B - Taxi(贪心)
Problem description After the lessons n groups of schoolchildren went outside and decided to visit P ...
- Could not create the view: An unexpected exception was thrown. Myeclipse空间报错
我的路径D:\MyEclipse 10\.metadata\.plugins\org.eclipse.core.runtime\.settings 我也遇到过这个问题,就是工作空间的问题好像是删除你工 ...
- Java 判断字符串的存储长度
判断前台输入项的长度应该都会碰到String.length() 判断出来没有超出最大长度,存到数据库就超出长度的问题,oracle字符集是gbk的不太清楚,如果是UTF-8,中文是占三个字符的,所以 ...
- AndroidStudio怎样导入library项目库
先打开一个Project,然后将libraryr的项目作为module进行导入: File菜单->import module菜单 以上只是导入进来,还没有作为与project真正有效的一部分.需 ...
- 如何写出高性能SQL语句(文章摘自web开发者)
(声明:本文内容摘自web开发者,仅供收藏学习之用,如有侵权请作者联系博主,博主将在第一时间删除) 原文地址:http://www.admin10000.com/document/484.html 1 ...
- 如何实现MySQL数据库使用情况的审计
如何实现MySQL数据库使用情况的审计 最佳答案 mysql的审计功能 mysql服务器自身没有提供审计功能,但是我们可以使用init-connect + binlog的方法进行mysql的操 ...
- Redis 通用key操作命令
1.在redis里面允许模糊查询key,有3个通配符:*,?,[]. *:通配任意字符 ?:通配单个字符 []:通配中括号内的某个字符 例如: 2.randomKey 随机返回所有key中的某个 3. ...
- 集合运算(UNION)
表的加法 集合运算:就是满足统一规则的记录进行的加减等四则运算. 通过集合运算可以得到两张表中记录的集合或者公共记录的集合,又或者其中某张表中记录的集合. 集合运算符:用来进行集合的运算符. UNIO ...
- 写代码怎能不会这些Linux命令?
转自:https://zhuanlan.zhihu.com/p/28674639?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=to ...