Java多线程学习笔记(二)
三 多线程执行的共享数据和非共享数据:
共享数据:就是每个线程执行的时候共享数据使用,比如这个线程一个为5的数据,减少为4之后,另一个线程执行拿到的数据是4,两个线程执行的数据是共享的。
非共享数据:各个线程执行的数据不受其他线程数据的改变而改变。
1 非共享数据:
package link.summer7c.test;
public class Test{
public static void main(String[] args){
MyThread2 a=new MyThread2("A");
MyThread2 b=new MyThread2("B");
MyThread2 c=new MyThread2("C");
a.start();
b.start();
c.start();
}
}
class MyThread2 extends Thread{
private int count=5;
public MyThread2(String name){
super();
this.setName(name);
}
public void run(){
super.run();
while(count>0){
count--;
System.out.println(this.currentThread().getName()+":count:"+count);
}
}
}
程序运行结果为:
C:count:4
B:count:4
A:count:4
B:count:3
C:count:3
C:count:2
C:count:1
C:count:0
B:count:2
A:count:3
B:count:1
A:count:2
B:count:0
A:count:1
A:count:0
从结果我们可以看见,3个线程的数据之间互不影响,变量减少按照各自的减法进行。这就是非共享的数据,这种做法通常在一些多线程并发操作中使用,各个数据没有相互影响。
2 共享数据:
各个线程之间的数据是共享的,他们的数据受其他线程的运行而影响。
package link.summer7c.test;
public class Test{
public static void main(String[] args){
MyThread3 myThread=new MyThread3();
Thread a=new Thread(myThread,"A");
Thread b=new Thread(myThread,"B");
Thread c=new Thread(myThread,"C");
a.start();
b.start();
c.start();
}
}
class MyThread3 extends Thread{
private int count=4;
public void run(){
super.run();
count--;
System.out.println(this.currentThread().getName()+":count:"+count);
}
}
运行结果有很多种:
A:count:3
B:count:2
C:count:1
或者:
A:count:2
B:count:2
C:count:1
这种运行结果可能会发现有些问题,就是出现了相同的数据。
这个之后来讨论。
构造方法public Thread(Runnable target, String name)
共享数据的main方法中并不是new了多个对象,而是new个一个我们的类,然后new了3个Thread对象,调用了public Thread(Runnable target, String name)构造方法。
共享数据的时候还要不能出现循环,如果一个线程开始循环,那么其他循环就得不到运行的机会了。
三 线程安全的问题
在共享数据的时候,我们会看到多个运行及结果很奇特,比如在运行的时候会出现2个相同的数据,这就牵扯到了线程安全的问题,如果在多线程中出现了:
A:count:2
B:count:2
C:count:1
这种情况,就称作线程不安全。举个例子,我们再抢火车票,每个客户都是一个线程,那么我们需要线程之间是安全的,不然就会发生两个座位同时被买走的可能性,发生这样的情况很不好。为了解决线程安全性我们可以使用同步锁,也就是每个线程之间要同步数据,不能发生线程之间不同步导致的线程不安全情况。多线程之间的同步可以通过在run方法之前加入synchronized关键字来实现,这样就不会出现两个数据相同的情况了。
class MyThread3 extends Thread{
private int count=4;
synchronized public void run(){
super.run();
count--;
System.out.println(this.currentThread().getName()+":count:"+count);
}
}
synchronized可以在任意对象和方法上加锁,加锁的代码称为“互斥区”或者临界区。加上锁之后线程会是这样的:
程序运行->拿锁->如果拿到锁了执行synchronized里的代码
->如果没有拿到就不断的尝试知道拿到->执行synchronized里的代码
=========================================

Java多线程学习笔记(二)的更多相关文章
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
- Java IO学习笔记二
Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...
- Java多线程学习(二)synchronized关键字(2)
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79670775 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java多线程学习(二)synchronized关键字(1)
转载请备注地址: https://blog.csdn.net/qq_34337272/article/details/79655194 Java多线程学习(二)将分为两篇文章介绍synchronize ...
- Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer
作者:Grey 原文地址:Java IO学习笔记二:DirectByteBuffer与HeapByteBuffer ByteBuffer.allocate()与ByteBuffer.allocateD ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- java 多线程学习笔记
这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...
- Java多线程学习笔记--生产消费者模式
实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...
随机推荐
- Cassandra概念学习系列之Windows里下载且安装配置Cassandra(最新的3.11.1版本)(图文详解)
不多说,直接上干货! 最近我开始在windows环境中使用Cassandra,虽然在Cassandra站点的安装命令非常清楚和精简,我仍然在环境配置上遇到一些问题.所以我想为后来者分享下我的经验. ...
- python跳出多重循环
# -*- coding=utf-8 -*- """ 如何结束多重循环,在单层循环中,可以用break跳出循环,那两层,三层呢? """ # ...
- 使用C++11 开发一个半同步半异步线程池
摘自:<深入应用C++11>第九章 实际中,主要有两种方法处理大量的并发任务,一种是一个请求由系统产生一个相应的处理请求的线程(一对一) 另外一种是系统预先生成一些用于处理请求的进程,当请 ...
- JAVA练手--数组
//数组 public static void main(String[] args) { //1. 数组排序和查找 { int[] intA = {5, 4, 2, 3, 1}; String[] ...
- Apache mod_rewrite
mod_rewrite是Apache的一个非常强大的功能,它可以实现伪静态页面.下面我详细说说它的使用方法!对初学者很有用的哦! 1.检测Apache是否支持mod_rewrite phpinfo() ...
- 微信小程序(二)框架的基本组成
安装好 微信web开发者工具后. 让我们来了解一下工具的框架,上图: 工具总共分为三个部分,左上角红框框: 模拟器:模拟手机小程序界面,模拟器左上角可以选择手机型号,右上角红框处,千万别选成Offic ...
- 怎么用PHP发送HTTP请求(POST请求、GET请求)?
file_get_contents版本: 01 /** 02 * 发送post请求 03 * @param string $url 请求地址 04 * @param array $post_data ...
- 关于设置服务器为https服务器
主要是设置IIS: step1:打开Internet 信息服务(IIS)管理器——选择网站,编辑绑定 step2:添加https,如下图,这样如果不设置SSL的话就两种都可以进去网站 如果想要设置 ...
- [javaSE] 数据结构(二叉树-遍历与查找)
前序遍历:中,左,右 中序遍历:左,中,右 后序遍历:左,右,中 二叉树查找 从根节点进行比较,目标比根节点小,指针移动到左边 从根节点进行比较,目标比根节点大,指针移动到右边 /** * 前序遍历 ...
- Java开发学习--Java 中基本类型和包装类之间的转换
Java 中基本类型和包装类之间的转换 基本类型和包装类之间经常需要互相转换,以 Integer 为例(其他几个包装类的操作雷同哦): 在 JDK1.5 引入自动装箱和拆箱的机制后,包装类和基本类型之 ...