线程

java 多线程之:synchronized

只愿长相守 提交于 2020-03-28 06:53:33
synchronized原理 在java中,每一个对象有且仅有一个同步锁。这也意味着,同步锁是依赖于对象而存在。 当我们调用某对象的synchronized方法时,就获取了该对象的同步锁。例如,synchronized(obj)就获取了“obj这个对象”的同步锁。 不同线程对同步锁的访问是互斥的。也就是说,某时间点,对象的同步锁只能被一个线程获取到!通过同步锁,我们就能在多线程中,实现对“对象/方法”的互斥访问。 例如,现在有两个线程A和线程B,它们都会访问“对象obj的同步锁”。假设,在某一时刻,线程A获取到“obj的同步锁”并在执行一些操作;而此时,线程B也企图获取“obj的同步锁” —— 线程B会获取失败,它必须等待,直到线程A释放了“该对象的同步锁”之后线程B才能获取到“obj的同步锁”从而才可以运行。 synchronized基本规则 我们将synchronized的基本规则总结为下面3条,并通过实例对它们进行说明。 第一条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或者“synchronized代码块”的访问将被阻塞。 第二条: 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程仍然可以访问“该对象

java多线程实现卖票程序(synchronized)

♀尐吖头ヾ 提交于 2020-03-28 06:52:22
本文采用java多线程实现了模拟车站多个车票卖票的功能。 关键词:java多线程 并发 共享资源 互斥访问 实现runnable接口 volatile 线程同步。 关键:线程同步,因为创建了多个线程,那么卖票部分代码应该上锁来保证线程对此关键代码的互斥访问,上锁的方式有两种,一种是synchronized隐式锁,另一种是Lock.lock()显式锁。 问题1:两种锁的区别:使用显示锁可以做到更细的控制粒度。比如可以设置一个线程试图获取锁,但是设定时间内获取锁失败可以进行其他操作等,这些事synchronized锁无法实现的。 问题2:synchronized作用讲解 一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。 二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。 三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。 四、第三个例子同样适用其它同步代码块

线程同步

泄露秘密 提交于 2020-03-28 06:51:08
-----------siwuxie095 同步代码块 : 在代码块前加上 synchronized 关键字,则此代码块就称为 同步代码块 同步代码块格式: 同步方法 : 除了 代码块 可以同步,方法也可以同步 同步方法格式: 代码: package com.siwuxie095.thread; /** * 同一辆车共 5 张车票,有 3 个售票窗口 * 3 个售票窗口即 3 个线程 * * @author siwux * */ class MyRunnableDemo implements Runnable{ private int ticket= 5 ; // 复写 run() 方法 public void run() { // 循环次数超过 5 次即可,这里设为 10 for ( int i = 0 ; i < 10 ; i++) { // 同步代码块:传入 this 即可 // 如果没有同步代码块,则就会出现卖到 0 和 -1 (注意:这里设置了 ticket>0 的条件) // 出现这种情况的原因就是资源无法共享。要解决类似的资源共享的问题就要用到同步 // 设置同步后执行速度明显变慢,但是实现了资源共享 synchronized ( this ) { // 如果当前的车票大于 0 if (ticket> 0 ) { try { // 票不会一下就卖光,设置买票等待时间

Java线程的同步 - synchronized

*爱你&永不变心* 提交于 2020-03-28 06:50:34
为什么要在线程里面使用同步 - synchronized 首先看个列子: 假设系统里面有5张票,有个卖票的系统,执行完,打印的结果是这样的: public class RunDemo05 implements Runnable { private int count = 5; public void run() { for(int i=0;i<10;i++) { sale(); } } public void sale(){ if (count>0) { try{ Thread.sleep(1000); } catch(Exception e){ e.printStackTrace(); } System.out.println(count--); } } public static void main(String[] args) { RunDemo05 r = new RunDemo05(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t3 = new Thread(r); t1.start(); t2.start(); t3.start(); } } 结果: 5 3 4 2 1 2 出现这样的原因: 在同一时刻有多个线程访问count数据,所以导致这种结果。

Java开发笔记(九十七)利用Runnable启动线程

丶灬走出姿态 提交于 2020-03-28 06:48:04
前面介绍了线程的基本用法,按理说足够一般的场合使用了,只是每次开辟新线程,都得单独定义专门的线程类,着实开销不小。注意到新线程内部真正需要开发者重写的仅有run方法,其实就是一段代码块,分线程启动之后也单单执行该代码段而已。因而完全可以把这段代码抽出来,把它定义为类似方法的一串任务代码,这样能够像调用公共方法一样多次调用这段代码,也就无需另外定义新的线程类,只需命令已有的Thread去执行该代码段就好了。 在Java中定义某个代码段,则要借助于接口Runnable,它是个函数式接口,唯一需要实现的只有run方法。之所以定义成函数式接口的形式,是因为要给任务方法套上面向对象的壳,这样才好由外部去调用封装好的任务对象。现在有个阶乘运算的任务,希望开个分线程计算式子“10!”的结果,那便定义一个实现了Runnable接口的任务类FactorialTask,并重写run方法补充求解“10!”的代码逻辑。编写完成的FactorialTask类代码示例如下: // 定义一个求阶乘的任务 private static class FactorialTask implements Runnable { @Override public void run() { int product = 1; for (int i=1; i<=10; i++) { product *= i; }

Java 多线程总结

限于喜欢 提交于 2020-03-28 06:29:36
昨天熬了个通宵,看了一晚上的视频,把java 的多线程相关技术重新复习了一遍,下面对学习过程中遇到的知识点进行下总结。 首先我们先来了解一下进程、线程、并发执行的概念:   进程是指: 一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。 线程是指: 进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。 一般来说, 当运行一个应用程序的时候,就启动了一个进程,当然有些会启动多个进程。启动进程的时候,操作系统会为进程分配资源,其中最主要的资源是内存空间,因为程序是在内存中运行的。 在进程中,有些程序流程块是可以乱序执行的,并且这个代码块可以同时被多次执行。实际上,这样的代码块就是线程体。线程是进程中乱序执行的代码流程。当多个线程同时运行的时候,这样的执行模式成为并发执行。 线程的状态 1、线程共有下面4种状态: 新建状态(New): 新创建了一个线程对象,当你用new创建一个线程时,该线程尚未运行。 就绪状态(Runnable): 线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。 运行状态(Running):

C#多线程与异步的区别

99封情书 提交于 2020-03-28 06:26:26
  http://kb.cnblogs.com/page/116095/ 随着拥有多个硬线程CPU(超线程、双核)的普及,多线程和异步操作等并发程序设计方法也受到了更多的关注和讨论。本文主要是想与园中各位高手一同探讨一下如何使用并发来最大化程序的性能。    多线程和异步操作的异同   多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别。    异步操作的本质    所有的程序最终都会由计算机硬件来执行,所以为了更好的理解异步操作的本质,我们有必要了解一下它的硬件基础。 熟悉电脑硬件的朋友肯定对DMA这个词不陌生,硬盘、光驱的技术规格中都有明确DMA的模式指标,其实网卡、声卡、显卡也是有DMA功能的。DMA就是直接内存访问的意思,也就是说,拥有DMA功能的硬件在和内存进行数据交换的时候可以不消耗CPU资源。只要CPU在发起数据传输时发送一个指令,硬件就开始自己和内存交换数据,在传输完成之后硬件会触发一个中断来通知操作完成。这些无须消耗CPU时间的I/O操作正是异步操作的硬件基础。所以即使在DOS这样的单进程(而且无线程概念)系统中也同样可以发起异步的DMA操作。( 注意文章结尾,c#中的异步跟这个DMA貌似无关

线程上下文切换的性能损耗测试

这一生的挚爱 提交于 2020-03-28 05:39:45
线程上下文切换的性能损耗到底有多少,一直没有直观的理解,今天写个程序测试一下。先看看下面的程序( 点击下载 ): ThreadTester是所有Tester的基类。所有的Tester都干的是同样一件事情,把counter增加到100000000,每次只能加1。 1: public abstract class ThreadTester 2: { 3: public const long MAX_COUNTER_NUMBER = 100000000; 4: 5: private long _counter = 0; 6: 7: //获得计数 8: public virtual long GetCounter() 9: { 10: return this._counter; 11: } 12: 13: //增加计数器 14: protected virtual void IncreaseCounter() 15: { 16: this._counter += 1; 17: } 18: 19: //启动测试 20: public abstract void Start(); 21: 22: //获得Counter从开始增加到现在的数字所耗的时间 23: public abstract long GetElapsedMillisecondsOfIncreaseCounter(); 24:

异步调用与多线程的区别

馋奶兔 提交于 2020-03-28 05:31:28
  随着拥有多个硬线程CPU(超线程、双核)的普及,多线程和异步操作等并发程序设计方法也受到了更多的关注和讨论。本文主要是想探讨一下如何使用并发来最大化程序的性能。    多线程和异步操作的异同   多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是,多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别。多线程是实现异步的一个重要手段,但不是唯一手段,对以一个单线程程序也可以是异步执行的。    异步操作的本质   所有的程序最终都会由计算机硬件来执行,所以为了更好的理解异步操作的本质,我们有必要了解一下它的硬件基础。 熟悉电脑硬件的朋友肯定对DMA这个词不陌生,硬盘、光驱的技术规格中都有明确DMA的模式指标,其实网卡、声卡、显卡也是有DMA功能的。DMA就是直 接内存访问的意思,也就是说,拥有DMA功能的硬件在和内存进行数据交换的时候可以不消耗CPU资源。只要CPU在发起数据传输时发送一个指令,硬件就开 始自己和内存交换数据,在传输完成之后硬件会触发一个中断来通知操作完成。这些无须消耗CPU时间的I/O操作正是异步操作的硬件基础。所以即使在DOS 这样的单进程(而且无线程概念)系统中也同样可以发起异步的DMA操作。异步编程的目的就是为了能够是实现并行

关于异步和多线程的关系

守給你的承諾、 提交于 2020-03-28 05:21:48
个人的理解是这样的: 1. 异步通信的意思是,当A发送完消息之后,不等待B的回应,继续执行之后的程序.在将来的某个时刻,A再来检查是否收到B的回应。 异步就是彼此独立,在等待某事件的过程中继续做自己的事,不需要等待这一事件完成后再工作。 2. 多线程是程序设计的逻辑层概念,它是进程中并发运行的一段代码。多线程可以实现线程间的切换执行。 3. 异步和同步是相对的,同步就是顺序执行,执行完一个再执行下一个,需要等待、协调运行。线程就是实现异步的一个方式。异步是让调用方法的主线程不需要同步等待另一线程的完成,从而可以让主线程干其它的事情。 异步和多线程并不是一个同等关系,异步是最终目的,多线程只是我们实现异步的一种手段。异步是当一个调用请求发送给被调用者,而调用者不用等待其结果的返回而可以做其它的事情。实现异步可以采用多线程技术或则交给另外的进程来处理。 来源: https://www.cnblogs.com/billy-chou/p/3928640.html