java线程与进程
Java线程与进程
进程与线程的关系
进程里面至少有一个线程,进程间的切换会有较大的开销
线程必须依附在进程上,同一进程共享代码和数据空间
多线程的优势
多线程可以达到高效并充分利用cpu
线程使用的方法
继承Thread类使用线程
public class Test{
public static void main(String[] args){
MyThread t = new MyThread("x1x");
t.start(); // 启动线程
}
}
// 自定义一个类,继承Thread类,重写run()方法
class MyThread extends Thread{
private Thread thread;
private String threadName;
public MyThread(String threadName){
this.threadName = threadName;
}
@override
public void run(){
System.out.println("线程名称:" + threadName);
for(int i = 0; i < 5; i++){
System.out.println("Thread:" + threadName + "-----" + i);
}
}
public void start(){
if(null == thread){
thread = new Thread(this, threadName);
thread.start();
}
}
}
继承Thread类
实现Runnable接口使用线程
public class Test{
public static void main(String[] args){
MyRunnable m = new MyRunnable("r1r");
m.start();
}
}
// 实现Runnable接口,实现run()方法
class MyRunnable implements Runnable{
private Thread thread;
private String threadName;
// 构造方法
public MyRunnable(String threadName){
this.threadName = threadName;
}
@override
public void run(){
System.out.println("线程名称: " + threadName);
for(int i = 0; i < 6; i++){
System.out.println("Thread: " + threadName + "----" + i);
}
}
public void start(){
if(null == thread){
thread = new Thread(this, threadName);
thread.start();
}
}
}
实现Runnable接口
实现Callable接口使用线程
public class MyCallable implements Callable<Integer>{
public static void main(String[] args){
MyCallable mc = new MyCallable();
// 这里的泛型里面填写的类型也与实现Callable时填写的一致
FutureTask<Integer> fTask = new FutureTask<>(mc);
new Thread(fTask, "带返回值的线程").start();
System.out.println(fTask.get()); // 拿到返回值
}
/*
* call()的返回值类型和实现Callable时填写的类型一致,比如这里是Integer类型,那么
* call()方法的返回值类型就是Integer类型
*/
@override
public Integer call() throws Exception{
for(int i = 0; i < 100; i++){
System.out.println(Thread.currentThread().getName() + "----" + i);
}
return i;
}
}
实现Callable接口
用匿名内部类的形式使用线程
public class Test{
public static void main(String[] args){
// 利用Thread类实现
new Thread(){
@override
public void run(){
while(true){
System.out.println(Thread.currentThread().getName());
}
}
}.start();
// 利用Runnable接口实现
new Thread(new Runnable(){
@override
public void run(){
while(true){
System.out.println(Thread.currentThread().getName());
}
}
}).start();
}
}
内部类形式调用
继承Runnable和Callable接口比继承Thread类的优势
- 适合多个相同的程序代码的线程去处理同一个资源
- 可以避免java中的单继承的限制
- 增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
线程的优先级
java中的线程是具有优先级的,优先级高的线程会获得更多的运行机会。
java中线程的优先级是用整数来表示的,取值范围是1 - 10
Thread类中有三个静态常量表示优先级:
static int MAX_PRIORITY 线程可以具有的最高优先级,取值为10
static int MIN_PRIORITY 线程可以具有的最低优先级,取值为1
static int NORM_PRIORITY 分配给线程的默认优先级,取值为5
如果要对线程设置优先级或者获取线程的优先级,可以使用Thread类的setPriority 和 getPriority方法分别得到和获取
线程的常用方法
sleep() 强迫线程睡眠
join() 等待线程终止
currentThread() 得到当前方法所在的线程
isDaemon() 一个线程是否为守护线程
setDaemon() 设置一个线程为守护线程
setName() 为线程设置名称
wait() 强迫线程等待
interrupt() 终止线程
notify() notifyAll() 通知线程继续执行
setPriority() 设置优先级
getPriority() 获取优先级
同步
使用synchronized同步锁
- 获得同步锁
- 清空工作内存
- 从主内存拷贝对象到工作内存
- 刷新主内存
- 释放同步锁
/*
* 这个程序的本意是第一个线程先输出zhangsan,然后第二个线程输出lisi
* 但是由于两个线程同步执行,第一个线程调用output()方法还未结束,第二个线程就已
*经开始调用output()方法
* 最终的输出就会是zlhiasnigsan
* 就好比两个工人在同一时间使用同一机器加工零件,那不就乱套了吗?
*/
public class synchronizedTest {
public static void main(String[] args) {
final Outputter o = new Outputter();
new Thread() {
public void run() {
o.output("zhangsan");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
o.output("lisi");
}
}).start();
}
}
class Outputter{
// 放在代码块前面
public void output(String name) {
for(int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
没有同步带来的问题
/*
* 在要调用的output()方法前面加上synchronized同步锁就可以解决上述问题
* 当使用同步锁后,同一对象在同一时间只允许一个线程使用
* 也就是说,第一个线程调用output()方法,在进入方法后,synchronized就
* 上锁了,后面的线程就不能调用了,必须等待当前线程执行完output()方法释放锁后
* 后面的线程才允许调用
* 就好比第一个工人要开始使用机器加工零件了,在使用机器前,他将房门锁住了,于是
* 后面
* 的工人便不能进房间使用机器,必须等工人一加工完零件,将锁打开,第二个工人才能
* 进去
* 加工零件
*/
public class synchronizedTest {
public static void main(String[] args) {
final Outputter o = new Outputter();
new Thread() {
public void run() {
o.output("zhangsan");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
o.output("lisi");
}
}).start();
}
}
class Outputter{
// 放在代码块前面
public synchronized void output(String name) {
for(int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
使用同步解决问题1
/*
* 第二种使用synchronized的方法就是将synchronized
* 放在要上锁的代码块前面,原理与上述一致
*/
public class synchronizedTest {
public static void main(String[] args) {
final Outputter o = new Outputter();
new Thread() {
public void run() {
o.output("zhangsan");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
o.output("lisi");
}
}).start();
}
}
class Outputter{
public void output(String name) {
// 放在代码块前面
synchronized(this) {
for(int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
使用同步锁解决问题2
synchronized(){
}的括号里面放的是需要互斥的对象,就是两个工人加工零件使用的同一个机器
使用volatile同步变量
volatile使变量对线程具有可见性

java线程与进程的更多相关文章
- JAVA线程和进程区别
1,JAVA线程和进程区别? (1)简单来讲一个运行的程序就是一个进程,一个进程中可以有多个线程(线程是程序执行的最小单元). (2)线程有四种状态:运行,就绪,挂起,结束 (3)使用多线程的好处 使 ...
- Java线程和进程相关面试题与答案总结
有几天没有写一写博客了,今天就带给大家一些面试题和参考答案吧! 这些都是上海尚学堂Java培训的学员去面试时遇到的问题,今天总结出来的是Java线程相关类的面试题.把参考答案和解析也发布出来,供大家学 ...
- 关于java线程、进程的一些问题
1.多核硬件上,java中同一个进程的多个线程可以运行在不同的CPU上么? 应该是可以的,在eclipse上面跑一个模拟程序,一个死循环的线程可以占用系统(4核,Win7)%的CPU,4个这样的线程刚 ...
- Java线程和进程
一.线程 1.什么是线程: 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.一个进程至少包含一个线程,也可以多个,线程属于进程. 2.Java中线程经历的四个 ...
- java线程,进程,多线程
(1)线程和进程 通俗一点,进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行. (2)java中实现线程的两种方式,第一种是继承Thre ...
- 菜鸡的Java笔记 第三十七 - java 线程与进程
线程与进程 线程与进程的区别 最早的的时候DOS 系统有一个特点:只要电脑有病毒,那么电脑就死机了,是因为传统的DOS 系统属于单进程的操作系统 ...
- java线程与进程的比较
线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元:而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任 ...
- java线程基础梳理
java线程 概述 进程:运行时概念,运行的应用程序,进程间不能共享内存 线程:应用程序内并发执行的代码段,可以共享堆内存和方法区内存,而栈内存是独立的. 并发理解:在单核机器上,从微观角度来看,一段 ...
- Java中的进程和线程
Java中的进程与线程 一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是 ...
随机推荐
- idea找不到package下的mapper.xml文件
由于开发人员使用不同的开发工具,导致eclipse的开发人员将mapper.xml文件习惯性的放到package下,以便查看,而eclipse编译时,不会忽略package下的xml以及dtl文件,所 ...
- Spring Framework 的 Assert断言
知识共享才能传播,博采众家之长,才能推陈出新!-- 参考 https://www.cnblogs.com/hwaggLee/p/4778101.html 一.什么是 Assert(断言)? Web 应 ...
- Spring知识点回顾(02)AOP
一.注解拦截 二.方法规则拦截
- Mego开发文档 - 从EF6/EFCore迁移到Mego
从EF6/EFCore迁移到Mego框架 如果您有EntityFragmework6或EntityFragmeworkCore的开发经验,在首次接触Mego框架时会发现这两个框架非常相似,本文将帮忙您 ...
- asp.net(C#)实现功能强大的时间日期处理类完整实例
作者:smartsmile2012 字体:[增加 减小] 类型:转载 时间:2016-06-30我要评论 这篇文章主要介绍了asp.net(C#)实现功能强大的时间日期处理类,封装了针对日期与时间的各 ...
- redis数据库各种数据类型的增删改查命令
redis的常用数据操作: redis是key-value的数据结构,每条数据都是一个键值对. 键的类型是字符串并且键不能重复. redis最基本数据类型是string 所以下面的操作可以省略引号&q ...
- spring cloud zipkin sleuth与spring boot aop结合后,启动慢
问题描述: 引入了spring cloud的监控starter,间接引入jooq. 又引入了 spring-boot-starter-web,所以间接引入aop. 参考下面资料后:https://gi ...
- 基于OpenCV单目相机的快速标定--源码、工程、实现过程
相机的标定是所有人走进视觉世界需要做的第一件事,辣么多的视觉标定原理解释你可以随便在网上找到,这里只讲到底如何去实现,也算是给刚入门的朋友做个简单的分享. 1.单目相机标定的工程源码 首先请到同性交友 ...
- POJ-2240 Arbitrage---判断正环+枚举
题目链接: https://vjudge.net/problem/POJ-2240 题目大意: 已知n种货币,以及m种货币汇率及方式,问能否通过货币转换,使得财富增加. 思路: 由于这里问的是财富有没 ...
- [转]Python爬虫框架--pyspider初体验
标签: python爬虫pyspider 2015-09-05 10:57 9752人阅读 评论(0) 收藏 举报 分类: Python(8) 版权声明:本文为博主原创文章,未经博主允许不得转载. ...