精华内容
下载资源
问答
  • 重温C#多线程共享 同步

    千次阅读 2018-04-29 17:24:51
    C#虽然晚出,但是依它那优雅的代码,清晰的逻辑,强大的功能库,让编程爱好者非常喜欢(我就是员)而多线程技术就是其中的项重温C#多线程共享 同步 using System; using System.Collections.Generic; using ...
    
    

    C#虽然晚出,但是依它那优雅的代码,清晰的逻辑,强大的功能库,让编程爱好者非常喜欢(我就是一员)

    而多线程技术就是其中的一项

    重温C#多线程共享 同步

    
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            public static object 加锁对象 = new object();
            static int 共享整数=1;
    
            public static Mutex 互斥体;
            public static int i = 0;
    
            static void Main(string[] args)
            {
                //线程共享
    
                //共享线程类 ASV = new 共享线程类();//实例化共享类
                //Thread[] B;//定义线程数组
                //B= new Thread[5];//实例化数组5个线程
                //for (int c = 0; c < 6; c++) 
                //{
                //    B[c]=new Thread(new ThreadStart(ASV.共享方法));//将线程输出
                //    B[c].Start();//输出
                //}
                //Console.ReadKey();
                //共享了一个值,这个值在被共享之后值会变成指定的值
                //如 共享数值A=5   被第一个共享-1之后 为4 被第2个共享之后加5 为9
    
                //lock 同步
    
                //Thread A = new Thread(new ThreadStart(对象1));
                //Thread B = new Thread(new ThreadStart(对象2));
                //A.Start();
                //B.Start();
                //Console.ReadKey();
                //给2个线程赋予  互拆锁
    
    
                //Mutex 类同步演示
                互斥体 = new
                 Mutex(true);
                Thread A = new Thread(new
                     ThreadStart(new 互类().线程1));
                Thread B = new Thread(new
                    ThreadStart(new 互类().线程2));
                A.Start();
                B.Start();
                Console.ReadKey();
    
                do {
                    if(Console.Read()=='e')
                A.Abort();B.Abort();
            } while (1 == 1);
                      
    
    
            }
    
            public static void 对象1()
            {
               
                
                    lock(加锁对象)//加锁 让它先访问
                    {
                        共享整数=共享整数+1;
                        Console.WriteLine("对象1开始,共享整数={0}",共享整数);
                        Thread.Sleep(200);
    
    
                    }
    
              
            }
            public static void 对象2()
            {
                lock(加锁对象)
                    {
                        共享整数=共享整数-1;//然后它再访问
                        Console.WriteLine("对象2开始,共享整数={0}",共享整数);
                        
                        Thread.Sleep(200);
                        Console.WriteLine("对象2退出,共享整数={0}", 共享整数);
    
    
                    }
             
            }
    
        }
        class 互类
        {
            public void 线程1()
            {
                do
                {Program.互斥体.WaitOne();
                    Program.i=Program.i+1;
                    Console.WriteLine("线程1开始,共享数据值i={0}",Program.i);
                    Thread.Sleep(1000);
                    Console.WriteLine("线程1结束,共享数据值i={0}",Program.i);
                    Program.互斥体.ReleaseMutex();
                    Thread.Sleep(1000);
                }while(1==1);
                
            }
            public void 线程2()
            {
                do
                {
                   // Program.互斥体.WaitOne();
                    Program.i = Program.i - 1;
                    Console.WriteLine("线程2开始,共享数据值i={0}", Program.i);
                    Thread.Sleep(1000);
                    Console.WriteLine("线程2结束,共享数据值i={0}", Program.i);
                   // Program.互斥体.ReleaseMutex();
                    Thread.Sleep(1000);
                } while (1 == 1);
            }
    
        }
    
        class 共享线程类
        {
            static int B = 1;//共享一个字段
            public void 共享方法()
            {
                Console.WriteLine("正在共享{0}", B++);
    
            }
        }
    }
    

    展开全文
  • 预想: 一个类 ClassA 中的一个类变量 public static int data = 100; 我起一个main方法 调用 ClassA.data = 200; 再起一个main方法 读取ClassA.data 获取的值就是200? 任意线程修改单例的ClassA 其他线程读取都...
  • 线程共享数据  a)继承Thread,那么我们可以创建很多个这样的,但是每这样的都是相互不关联的,也是说我们Thread中的内容每创建出来的都有份,因此它不适合作为数据共享的线程来操作。同时由于...
  • Java实现多线程,有两种方式:1.继承Thread;2.实现Runnable接口。下面这是通过继承Thread实现对共享资源的处理,供参考: public class TestThread { public static void main(String[] args){ ...

    Java实现多线程,有两种方式:1.继承Thread类;2.实现Runnable接口。下面这个是通过继承Thread实现对共享资源的处理,供参考:

    public class TestThread {
    
    	public static void main(String[] args){
    		MultiUseThread m = new MultiUseThread();
    		
    		Thread t1 = new Thread(m,"windows 1");
    		Thread t2 = new Thread(m,"windows 2");
    		Thread t3 = new Thread(m,"windows 3");
    		
    		t1.start();
    		t2.start();
    		t3.start();
    	}
    }
    
    class MultiUseThread extends Thread{
    
    	private int tickets = 100;
    	
    	public void run(){
    		while(tickets > 0){
    			System.out.println(tickets-- + "张票已被售卖,售卖窗口为" + Thread.currentThread().getName());
    		}
    	}
    
    }


    展开全文
  • 写在前面 本文全文以售票系统为例,简诉了java多线程间共享数据的两种方式、线程...多线程共享数据1.1 共享Runnable1.2 封装数据为对象2.线程同步与互斥2.1 上述代码存在的问题2.2 同步与互斥2.3 synchronized实现...

    写在前面

    本文全文以售票系统为例,简诉了java多线程间共享数据的两种方式、线程同步。文章可能还有很多不足,请大家谅解,欢迎大佬提意见。

    本文使用到的东西

    1. java
    2. eclipse 2019-11

    1.多线程共享数据

    1.1 共享Runnable

      当多个线程执行的内容相同,可以采用共享Runnable接口实现类对象的方式共享数据,将共享的数据作为Runnable对象的成员变量。
      这里我们以包含多个售票处的售票系统为例,每一个售票处一个线程,多个线程共享余票数变量。

    class TicketRunnable implements Runnable{
    	private int num;
    	
    	public TicketRunnable(int num) {
    		this.num=num;
    	}
    	@Override
    	public void run() {
    		for(int i=0;i<5;i++) {	//出售5张票
    			if(num>0) {
    				num--;
    				System.out.println(Thread.currentThread().getName()+":售票1张,余票"+num);
    			}else {
    				System.out.println(Thread.currentThread().getName()+":暂时无余票");
    			}
    		}
    	}
    }
    public class 多线程共享数据 {
    	public static void main(String[] args) {
    		Runnable runnable = new TicketRunnable(8);	//初始化8张余票
    		new Thread(runnable,"武汉售票点").start();
    		new Thread(runnable,"北京售票点").start();
    	}
    }
    

    1.2 封装数据为对象

      当多个线程执行的是相同的操作时可以采用共享Runnable对象的方法来共享变量,执行不同操作时这个方法就不适用,可以将共享的数据封装成对象,多个线程共享该对象。
      以售票系统为例,一个线程执行退票,一个线程执行售票。

    class Ticket{
    	private int num;
    	public Ticket(int num) {
    		this.num=num;
    	}
    	public void sell() {
    		if(num>0) {
    			num--;
    			System.out.println(Thread.currentThread().getName()+":售票1张,余票"+num);
    		}else {
    			System.out.println(Thread.currentThread().getName()+":暂时无余票");
    		}
    	}
    	public void returned() {
    		num++;
    		System.out.println(Thread.currentThread().getName()+":退票1张,余票"+num);
    	}
    }
    public class 多线程共享数据 {
    	public static void main(String[] args) {
    		Ticket ticket = new Ticket(8);	//初始化为8张票
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				for(int i=0;i<8;i++) {
    					ticket.sell();//售票
    				}
    			}
    		},"售票处").start();
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				for(int i=0;i<8;i++) {
    					ticket.returned();//退票
    				}
    			}
    		},"退票处").start();
    	}
    }
    

    2.线程同步与互斥

    2.1 上述代码存在的问题

    以共享Runnable对象实现同步的方式为例,运行该程序,运行结果如下:

    武汉售票点:售票1张,余票6
    武汉售票点:售票1张,余票5
    北京售票点:售票1张,余票6
    武汉售票点:售票1张,余票4
    武汉售票点:售票1张,余票2
    北京售票点:售票1张,余票3
    北京售票点:售票1张,余票0
    北京售票点:暂时无余票
    北京售票点:暂时无余票
    武汉售票点:售票1张,余票1
    

      我们设置的初始票数为8,查看运行结果,余票数量并不是从7开始递减,而是从6开始,而且并不是递减。出现该问题是因为武汉售票点将票数减1还未输出的时候,北京售票点也将票数减1,这时候输出结果就是6了。不是按递减输出也同样是因为读取了数据还未输出,另一个线程执行了卖票输出。对TicketRunnable的run()方法稍加修改,修改为

    	@Override
    	public void run() {
    		for(int i=0;i<5;i++) {	//出售5张票
    			synchronized (this) {
    				if(num>0) {
    					num--;
    					System.out.println(Thread.currentThread().getName()+":售票1张,余票"+num);
    				}else {
    					System.out.println(Thread.currentThread().getName()+":暂时无余票");
    				}
    			}
    		}
    	}
    

    此时,又是按递减顺序输出程序内容,因为synchronized给代码块添加了同步锁,将修改值和取值的操作进行了同步,所以不会在出现乱序、输出余票不正确的情况。

    2.2 同步与互斥

    1. 什么是互斥?
    在计算机中很多资源都是有限的,这种有限资源叫做临界资源。多个进程争抢同一个临界资源,抢到了可以运行,没抢到就无法运行。互斥就是争夺临界资源进程的间接制约关系。 例如多个打印线程争夺一台打印机资源,进程间就形成了互斥。

    2. 什么是同步?
    同步是协调多个相互关联线程合作完成任务,彼此之间存在一定约束,执行顺序往往是有序的。 同步是进程间的直接制约关系,例如供销系统,当仓库满了需要停止供货,仓库空了无法出货,此时供货进程和销货进程就形成了同步关系。

    2.3 synchronized实现同步

    synchronized可用于修饰方法、静态方法和代码块

    //对象锁,修饰方法
    synchronized void a() {
    
    }
    //类锁,修饰静态方法
    synchronized static void b() {
    
    }
    void c() {
    	//对象锁,修饰代码块
    	synchronized (this) {
    			
    	}
    	//类锁,修饰代码块
    	synchronized (Ticket.class) {
    
    	}	
    }
    

    2.4 ReentrantLock实现同步

    1.使用

    ReentrantLock lock = new ReentrantLock();
    lock.lock();	//加锁
    lock.unlock();	//解锁
    

    2.实现上述的售票同步

    class TicketRunnable implements Runnable{
    	private int num;
    	ReentrantLock lock = new ReentrantLock();
    	
    	public TicketRunnable(int num) {
    		this.num=num;
    	}
    	@Override
    	public void run() {
    		for(int i=0;i<5;i++) {	//出售5张票
    			lock.lock();
    			if(num>0) {
    				num--;
    				System.out.println(Thread.currentThread().getName()+":售票1张,余票"+num);
    			}else {
    				System.out.println(Thread.currentThread().getName()+":暂时无余票");
    			}
    			lock.unlock();
    		}
    	}
    }
    public class 多线程共享数据 {
    	public static void main(String[] args) {
    		Runnable runnable = new TicketRunnable(8);	//初始化8张余票
    		new Thread(runnable,"武汉售票点").start();
    		new Thread(runnable,"北京售票点").start();
    	}
    }
    

    3.总结

    synchronized实现的是同步还是互斥这一点有些难理解,网上也有说synchronized是互斥锁的,synchronized实现的是修饰的内容同步。有不清楚的地方欢迎评论留言,看到的我都会回复的。本文到此结束,有什么不足的地方请大家不吝指正。

    展开全文
  • 多线程时, 几线程间输出信息是交叉在一起的, 但你又没有区分是哪个线程输出的, 所以你自己就误认为是同一个线程输出的东西被改变了. 实际上是你自己的理解错误. 所有线程都用cout输出内容,你如何判断哪些内容...

    对于一个局部变量应该是各线程独立的,一个线程不会改变另一个线程的临时变量。

    多线程时, 几个线程间输出信息是交叉在一起的, 但你又没有区分是哪个线程输出的, 所以你自己就误认为是同一个线程输出的东西被改变了.  实际上是你自己的理解错误.

    所有线程都用cout输出内容,你如何判断哪些内容是哪个线程输出的,
    而且cout是一个全局变量,多线程同时访问需要加锁,否则会出现一些莫名其妙的情况

     

    结论: 局部变量是不会被修改的,而全局变量则很容易就被修改了,而你却还不知道。

    //

    多线程中,不同线程调用同一个函数,使用的是同一份代码还是不同线程用函数的多个拷贝?为什么?即每个线程用一个拷贝函数。
    不同线程中调用函数的局部变量是否指向的都指向同一个?

    每个线程有自己的堆栈,所以调用函数时对函数的相关参数也是各有一份的,不用担心;只是全局变量需要考虑同步。

    展开全文
  • Java多线程共享资源

    千次阅读 2016-11-10 21:46:00
    多线程中的一个核心问题就是对共享资源的读写问题。你永远都不知道一个线程何时在运行。如果同时有多线程对一个对象进行读写,结果就会出现脏数据接下来展示一个多线程同时对一个对象进行读写出现脏数据的案例。...
  • 多线程线程资源共享问题

    千次阅读 2017-12-01 18:25:11
    多线程的环境下, 由于公共资源可能会被多个线程共享, 也就是多线程可能会操作( 增、删、改等 )同一资源. 当多线程操作同一块资源时, 很容易导致数据错乱或发生数据安全问题, 即: 数据有可能丢失, 有可能增加...
  • Spring里多线程处理共享一个事务

    万次阅读 2017-12-27 16:02:58
    我通过自己写持久层代码,实现了多线程处理享受一个事务,一个线程报错所有线程回滚.但是真正能实现这功能的还在研究中.希望有懂的大神,提供下思路!@Service public class TestServiceImpl2 implements TestService ...
  • 多线程共享变量方式

    千次阅读 2015-08-25 17:15:06
    多线程共享变量的三种方式
  • 多线程不同步读写共享资源

    千次阅读 2011-12-25 18:20:50
    我在很早的时候就听说多线程不同步是可以读写共享资源的。这听起来感觉挺好,因为一旦同步线程,将在同步线程上花去一定的CPU时间片. 这一切都是真的,但是,不同步线程的条件是:只开两线程,读线程在写线程之后...
  • Java多线程共享受限资源

    千次阅读 2013-12-18 14:31:12
    即在一个线程的任务中,会对一个多线程共享的数据进行操作,在操作完成之前,对数据的更改对其他线程可见,此时,如果线程挂起,并驱动其他线程任务,则其他线程任务会访问到这数据的中间状态,即访问到错误的数据...
  • 多线程同步访问共享内存

    千次阅读 2012-05-07 19:37:43
    下面讨论的是特定于网络编程中多线程共享内存的同步访问,原理可以用于其它应用. 首先看看创建线程函数: #include int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(* func) ...
  • 如题,buffer是NIO中比较重要的概念,实际程序运行过程中,是在每线程中创建buffer,还是创建一份buffer,多个线程共享?...如果是多个线程共享一个buffer,那么如何确保数据读写的安全与同步的?
  • 1. 操作相同时,写一个 Runnable 实现,内部设置成员变量,run 方法修改该变量,将该Runnable传给不同Thread使用; 2. 操作不同时,在Thread调用实例化一个数据实例,传递给不同Runnable处理,再把不同的...
  • Java多线程共享变量控制

    千次阅读 2017-09-07 15:39:48
    多个线程同时对主内存的一个共享变量进行读取和修改时,首先会读取这变量到自己的工作内存中成为一个副本,对这副本进行改动之后,再更新回主内存中变量所在的地方。 (由于CPU时间片是以线程为最小单位
  • 如果一个类通过继承Thread来实现多线程的话,则不适合多个线程共享资源,而通过实现Runnable就可以做到这一点,下面给lz举例子: Java code class MyTheard extends Thread{ private int num = 5;//不能声明为...
  • 线程占有的都是不共享的,其中包括:栈、寄存器、状态、程序计数器 ...线程共享的内容包括: 进程 代码段 进程 数据段 进程打开的文件描述符、 信号的处理器、 进程的当前目录和 进程用户 ID 与进程组 ID ...
  • 多线程-共享全局变量问题

    千次阅读 2019-08-08 18:45:28
    文章目录多线程-共享全局...假设有两线程t1和t2,都要对一个变量g_num进行运算(+1),两进程t1和t2分别对g_num各加10次,g_num的最终结果? import threading import time g_num=0 def work1(num): global g...
  • 多线程操作同一个变量

    万次阅读 2019-03-13 15:52:37
    在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这关键字,在进行多线程并发处理的时候就可以万事大吉。 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 ...
  • C#多线程共享数据

    万次阅读 2007-03-24 16:39:00
    多线程编程中,我们经常要使用数据共享.C#中是如何实现的呢?很简单,只要把你要共享的数据设置成静态的就可以了.关键字static .如下: static Queue q1=new Queue(); static int b=0; 在这里我定义了一个整形变量b和...
  • java 多线程调用单例同一个方法

    千次阅读 2018-03-14 13:17:20
    1,java多线程调用 单例一个的方法是不会排队的,因为jvm 在每线程下,都有份 对调用方法的引用。 2,多线程调用的同一个对象的同一个方法: 如果方法里无成员变量,不受任何影响; 如果方法里有...
  • synchronized 实际上是对访问修改共享变量的代码块进行加互斥锁,多个线程对synchronized代码块的访问时,某时刻仅仅有一个线程在访问和修改代码块中的内 容(加锁),其他所有的线程等待该线程离开代码块时(释放...
  • 最近在看多线程时,一直迷茫为什么继承Thread多线程不能实现资源共享,但是实现Runnable接口的多线程却能实现资源共享,先看段经典的卖票多线程,将程序修改一下,使运行结果直观。 首先是实现Runnable接口来...
  • 多线程同步互斥实例——多个线程共享数据

    千次阅读 热门讨论 2016-04-26 17:14:30
    • 实例问题  设计4个线程,其中两个线程每次对j增加1,另外... 由题目可知道,我们需要创建4个线程,实现两方法,分别是给变量加1,和对同一个变量减1。这里面,所有的方法,必须要保证变量同步。所以,我们可以使
  • 多线程():创建线程和线程的常用方法

    万次阅读 多人点赞 2018-09-01 19:14:23
    了解并发编程:实际工作中很少写多线程的代码,这部分代码一般都被人封装起来了,在业务中使用多线程的机会也不是很多(看具体项目),但是作为一个高级程序员如果不会多线程是说不过去的。 二:进程与线程 ...
  • 实现多线程同步访问共享资源两种方式 synchronzied关键字+Object的wait/...一个类中存在普通成员变量,多线程中同时运行同一个类实例的实例方法,会共享访问普通成员变量,产生竞争,存在线程安全问题。需用实...
  • JAVA多线程——共享变量

    千次阅读 2018-11-12 10:53:09
    【转载】Java多线程编程:变量共享分析(Thread) 原博客网址:https://www.cnblogs.com/xudong-bupt/archive/2013/05/22/3087864.html 今天看到java的多线程,感到十分激动,之前就在python中使用过多...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 617,834
精华内容 247,133
关键字:

多线程共享同一个类