精华内容
下载资源
问答
  • java多线程编程注意问题

    千次阅读 2014-06-17 11:37:40
    java多线程编程注意问题 多线程的概念问度娘 ,大部分是千篇一律的。对于编程经验不是很丰富的程序员是比较难消化的。 作者从实际应用的角度来分析java多线程编程应注意问题。 应用场景假设: 一个影院有三...
    java多线程编程注意问题
    

    多线程的概念问度娘 ,大部分是千篇一律的。对于编程经验不是很丰富的程序员是比较难消化的。
    作者从实际应用的角度来分析java多线程编程应注意的问题。
    应用场景假设:
    一个影院有三个售票口,
    分别用于向儿童、成人和老人售票。影院为每个窗口放有100张电影票,
    分别是儿童票、成人票和老人票。(一个售票员相当于一个CPU,电影院最多可提供3名售票员).
    问题:怎样使电影院售票速度最快。(很多人在排队等待买票)。
    那么可想而知,我们是开3个售票窗口,让3名售票员都动起来。这就是多线程。

    在java平台多线程编程的程序员都知道,线程编程有2种实现办法继承Thread 和实现Runnable接口。
    我们先来看用继承的办法实现。
    public class MutliThread  extends Thread{
        private int ticket=100;//每个线程都拥有100张票
        public void run(){
            while(ticket>0){
                
                System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    测试类
    public class MutliThreadDemo {
        public static void main(String [] args){
            MutliThread m1=new MutliThread("Window 1");
            MutliThread m2=new MutliThread("Window 2");
            MutliThread m3=new MutliThread("Window 3");
            m1.start();
            m2.start();
            m3.start();
        }
        }

    问题2 。如果影院的票总计是100张,3名售票员同事售票。上述继承的办法是否能满足要求。
    经过分析明显不能满足,因为无法实现多线程资源共享。这个时候我们就需要采用实现Runnable接口的办法。

    public class MutliThread  implements Runnable{
        private int ticket=100;//每个线程都拥有100张票
        public void run(){
            while(ticket>0){
                
                System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    测试类:

    public class MutliThreadDemo {
        public static void main(String [] args){
            MutliThread m=new MutliThread();
            Thread t1=new Thread(m,"Window "+i);
        Thread t2=new Thread(m,"Window "+i);
        Thread t3=new Thread(m,"Window "+i);
        t1.start();
        t2.start();
        t3.start();
        }
        }


    对于第2中多线程,我们的线程是不是安全,是执行了100次?答案是肯定的。
    作者将打印的语句进行了比对。确实是100次。
    如果将变量换成静态的,就是大于100次。是不满足我们的业务需求。

    其实写个多线程类并不难,难的是要分析我们的线程是不是安全的。这个安全就是满足我们的业务需求。

    那在多线程编程的时候,我们要注意什么问题了。
    总结:
    1.多线程共享资源,执行同一任务,需要Runnable接口。
    2 静态方法通常是安全的。静态成员变量是不安全的。
    3.如何解决我们的安全问题,通常的做法是锁机制,或者用普通成员变量。

    4.举例:HashMap  与 currentHashMap . 区别: hashmap 比currenthashmap执行效率要高。但线程不安全。 而currenthashmap线程是安全的。

    展开全文
  • 但是事实上并不是如此,在多线程使用这些类仍然会存在问题。这就让人迷茫了,明明是线程安全的,为什么还会出错呢。我的理解是,明明是线程安全的,但是这些集合并不一定能在多线程环境中不出问题。 先看一段测试...
        众所周知,Java中有一些被称为是线程安全的集合容器,但是这里的线程安全会让人误以为在多线程环境中去使用这些容器就可以放心使用,包打天下。但是事实上并不是如此,在多线程中使用这些类仍然会存在问题。这就让人迷茫了,明明是线程安全的,为什么还会出错呢。我的理解是,明明是线程安全的,但是这些集合并不一定能在多线程环境中不出问题。
    先看一段测试代码:
    
    public class VectorTest {
    private static Vector testVector = new Vector();
    
    public static void main(String arg[]) {
        while (true) {
            for (int i = 0; i < 10; i++) {
                testVector.add(i);
                System.out.println("add" + i);
            }
            Thread remove = new Thread() {
                @Override
                public void run() {
                    try {
    
                        for (int i = 0; i < testVector.size(); i++) {
                            testVector.remove(i);
                            System.out.println("remove" + i);
                            Thread.sleep(1000);
                        }
    
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
    
            Thread print = new Thread() {
                @Override
                public void run() {
                    try {
    
                        for (int i = 0; i < testVector.size(); i++) {
                            System.out.println(testVector.get(i));
                            Thread.sleep(1000);
                        }
    
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
    
            print.start();
            remove.start();
            while (Thread.activeCount() > 10) ;
        }
    

    (这段代码是在看《深入理解java 虚拟机》这本书看到的)

     这段代码如果不运行可能看不出来问题,甚至运行了也不一定能暴露出问题,这里有一个很微妙的时机问题,等会儿具体分析。先看一下遇到的异常信息:
    

    出错信息

        这就是所谓的线程安全的类,在多线程中一样会有问题,那这是为什么呢,刚开始我也是百思不得姐,哦,是百思不得其解。后来在一篇博文当中看到了说Vector的contains方法和remove方法之前不具备原子性,这点给了提示。我现在认为出错的原因是在get和remove之间并没有在以上环境中做到同步,比方说,一个线程的get(2)操作发生时,正好遇到了remove操作的正在进行,这时get(2)这个操作就会阻塞,等待remove操作释放锁之后去操作。如果这时候remove操作的正好是remov(2)这个操作,等到去get的时候,这个元素已经没有了,get自然就只能是空欢喜一场。
        这里原因找到了,就该说解决办法了,在说解决办法之前,可能还会困惑,说好的线程安全呢,是不是童话里都是骗人的啊?我的理解是,线程安全并不代表使用安全,在实际使用时还是需要考虑当前环境中是否会出现问题的。那么问题来了,java提供线程安全的某些类的意义在哪里呢,反正还是会出问题。这就显得比较鸡肋了,但是也不能说没有意义,毕竟写程序还是要独立思考的。
        解决办法就比较简单了,在两个线程的run方法里加上synchronized (testVector),这样就会使得读取、删除线程中只会有一个对testVector进行操作,也就不会有上述情况出现。
        从这个错误来看的话,编程一定要谨慎,使用到的技术一定要深入了解,不能说不出问题,但是在出了问题之后能找出原因并解决,如果没有这个把握就不要轻易去使用,尤其在正式项目中,可能会让你欲哭无泪啊!
    
    展开全文
  • 使用单线程还是多线程问题

    千次阅读 2016-06-01 22:05:26
    对于处理时间短的服务或者启动频率高的用单线程,相反用多线程!  不论什么时候只要能用单线程就不用多线程,只有在需要响应时间要求比较高的情况下用多线程 某此操作允许并发而且该操作有可能阻塞时, 用多线程....

    对于处理时间短的服务或者启动频率高的要用单线程,相反用多线程! 
    不论什么时候只要能用单线程就不用多线程,只有在需要响应时间要求比较高的情况下用多线程

    某次操作允许并发而且该操作有可能阻塞时, 用多线程. 例如SOCKET, 磁盘操作.

    使用多线程编程可以给程序员带来很大的灵活性,同时也使原来需要复杂技巧才能解决的问题变得容易起来。但是,不应该人为地将编写的程序分成一些碎片,让这些碎片按各自的线程执行,这不是开发应用程序的正确方法。 线程很有用,但当使用线程时,可能会在解决老问题的同时产生新问题。

    例如要开发一个字处理程序,并想让打印功能作为单独的线程自己执行。这听起来是很好的主意,因为在打印时,用户可立即返回,开始编辑文档。但这样一来,在该文档被打印时文档中的数据就有可能被修改,打印的结果就不再是所期望的内容。也许最好不要把打印功能放在单独的线程中,不过,如果一定要用多线程的话,也可以考虑用下面的方法解决:第 一种方法是锁定正在打印的文档,让用户编辑其他的文档,这样在结束打印之前,该文档不会作任何修改;另一个方法可能更有效一些,即可以把该文档拷贝到一个临时文件中,打印这个临时文件的内容,同时允许用户对原来的文档进行修改。当包含文档的临时文件打印完成时,再删去这个临时文件。 
    通过上面的分析可以看出,多线程在帮助解决问题的同时也可能带来新问题。因此有必要弄清楚,什么时候需要创建多线程,什么时候不需要多线程。总的来说,多线程往往用于在前台操作的同时还需要进行后台的计算或逻辑判断的情况,而对于GUI(图形用户 接口),除了开发MDI(多文档界面)应用程序外,应尽量不使用多线程。

    多线程

    1、就如多了几副碗筷,可以抢占更多的系统资源,加快可以分割成独立执行单元的程序段运行

    2、提供良好的操作感受:不在UI主线程执行费时的作业(这些作业以线程运行)

    3、响应多个并行的请求

    简单的顺序执行方式不能满足要求的时候需要考虑多线程实现,或者有些多任务管理时也需要用到多线程,否则无法并行执行不同功能等等。

    单线程好比所有工作都要你自己干,那样你只能一样一样来,多进程好比你把这些工作分给若干人,大家同步进行,同步进行的好处是大家各干各的,除了接口外,其他工作都独立完成,这样不管是逻辑还是时间上都更加合理,就好象你们单位的若干部门协调工作一样。如果所有部门的工作都要你们老总一个人干,那就是单线程了。你明白了多线程的道理,想学多线程就非常简单了,mfc给你提供了若干实现多线程的函数和机制,直接调用就好,当然你还要注意资源共享,数据独占,互斥量等一些问题。

    ----------------------------------------------------------------------------------------------------------

    多线程就是可以同时做N件事情而不用堵塞在那里,

    多线程主要处理好同步问题

    什么时候该使用多线程,以及更恰当的多线程编程方法之讨论

    大约在写了一年左右的应用程序以后开始发生了一些困惑,在我写的程序中很多使用了多线程,我们了解使用线程的必要性,但是什么时候使用,以及该如何更好使用和管理多线程方面,我觉得值得思考。

    先讨论一下CApp类的实质。App就是一个用户界面线程。

    众所周知,CApp类继承于CWinThread类,是一个线程类,它的实例就是应用程序的主线程(一个用户界面线程)。App 实例化一个WinThread以后,主要的工作就是维护一个消息循环,直到收到程序退出消息,退出循环并终止线程。

    可见App对象使一个线程具有了处理消息的能力,而线程本身并没有这个能力,(了解这一点的目的在于弄清楚线程消息的概念。)拥有这种能力的线程也就是用户界面线程。

    一个线程就是一个代码的执行路径,如果没有App那么线程将按照一个固定的路径执行代码,不会受到任何外界情况的干扰(除非是CPU掉电,或者发生了硬件中断)。显然这不是我们想要看到的,于是如何控制一个线程的运行便成为了一个需要解决的问题,操作系统大多采用了消息机制的解决方案。所谓的消息是一种抽象的概念,其实就是一个操作系统的数据结构,一个可以被App主线程消息循环函数接受的参数。有了消息还不够,还必须要有发送消息的对象。这个对象一般是窗口,窗口作为用户界面线程的一部分用以接受各种事件,事件发生以后,窗口线程就向(自己)线程的消息队列里发送事件所对应的消息。消息的发出者还可以是主线程的其它子线程,也可以是主线程自身(窗口),当然也可以是操作系统。了解了消息机制的原理以后可以对我们编程提供一些帮助,比如,App主线程中不应该执行耗时很长的代码(比如循环,或者I/O操作,或者运算量很大的代码),这样才不会阻塞消息循环,导致界面“死掉”。 解决这个问题的方案就是创建子(辅助)线程来完成这些任务。

    这里要指出的几点是:(注:以下所说的子线程皆指辅助线程,而非界面线程)

    1.主线程不可以向子线程发送消息(但是反之则可以),这种做法本身没有任何意义,是概念不清的问题;

    2.当窗口要向子线程发送消息时;这个问题也是本文讨论的重点。首先,子线程没有处理消息的能力,它只能按照原先设定好的路径运行。所以窗口只能将消息发送给主线程,再由主线程想办法改变子线程的行为。主线程如何跟子线程通讯呢?(显然不能用消息)我所能想到的就是主线程改变一些公共域的值,然后由子线程通过轮询的方式来实现通讯。这也是windows给我们提供的方法,当我们使用AfxBeginThread或者CreateThread创建一个子线程的时候,会传入一个对象的指针,很显然,这个对象就是控制子线程的关键。

    至此了解了什么时候使用多线程的问题。

    第2个问题:如何更好的使用多线程

    首先是代码结构的问题。我们可以将子线程所要完成的功能全部在一个线程函数里实现,这显然在大多数时候是不合理的,第二种方法是通过父线程传递来的对象指针,调用该对象类的成员函数来实现所需的功能。这里引发新的问题,需不需要单独创建一个类来包装这些函数,还是将这些函数写在父线程的类中(包括辅助线程处理函数自己)。这两种方法从本质上来说似乎没有什么差别。后者的话,当我们需要改变子线程的行为时,只需要改变自身类成员变量就可以了,但是结构显得有些混乱。

    转自http://blog.163.com/loveyingchun_1314/blog/static/238242512011112284128908/

    展开全文
  • linux下使用多线程注意事项

    千次阅读 2010-10-09 10:52:00
    根据我的经验,linux下使用pthread库写多线程程序时,在调用系统调用/库函数方面,应注意至少如下几点:1、创建了线程后,不要再使用fork()/vfork()创建子进程2、尽量不使用signal机制3、...关于1,有个具体的教训。...

    根据我的经验,linux下使用pthread库写多线程程序时,在调用系统调用/库函数方面,应注意至少如下几点:

    1、创建了线程后,不要再使用fork()/vfork()创建子进程

    2、尽量不使用signal机制

    3、...

     

    关于1,有个具体的教训。我实现了一个动态库,该库的功能在一个独立线程里运行。同事A实现了另一个动态库,库的功能在也一个独立线程里运行。这两个库需要访问一设备,该设备只支持一个使用者访问,因此有个全局的信号量,来保证这两个线程能交替的访问该设备。我们的测试代码表明这两个库可以正常的配合工作。然后这两个库被交给同事B,集成到他的应用程序里。问题出现了,只要我和A的线程同时运行,几乎必然出现同时访问设备的错误情况,似乎用来保护的信号量失败了。多次检查库的代码,没有发现问题。偶然间,发现同事B的代码调用了system(),把system()调用替换成相应的代码实现,问题消失。原因在于system()实际上调用了fork()/vfork()。

    为什么在多线程调用fork会出现问题呢?我分析是因为fork会把当前进程复制到子进程,子进程也是多线程。注意在子进程执行fork()-exec()这段时间,子进程的其他线程也在运行,同时信号量也被复制到子进程中。因为父子进程有独立的信号量来保护设备,这样父进程访问设备的时候,子进程也可以访问设备,于是出现问题。

      linux下创建子进程和多线程冲突的根本原因在于fork会复制当前进程,而Windows创建子进程就没有这个问题。为什么会这样呢?个人认为可能是历史原因造成的。早期的unix注意是作为服务器使用,例如web/ftp服务等。在没有多线程支持的年代,服务器支持多用户访问支持的方法就是为每个用户创建一个服务子进程。服务子进程通常就是服务器本身,因此提供一个fork调用,是可以提高效率的。但是当初设计fork调用的时候,并没有考虑到多线程,导致与多线程冲突。unix的历史负担很多,比如线程局部存储(TLS),个人认为就是为了解决早期程序设计者喜欢大量使用全局变量和多进程提出的。

     

    那如果确实需要在多线程程序里运行另一个程序(而且只有可执行文件没有源代码)怎么办呢?可以把要执行的程序包装一下,多线程的主程序通过进程间通信的方式包装后的子进程通信。

     

    与关于第2点多线程与signal机制的问题,网上很多,大家搜索一下就有了,不多说了

     

     

    展开全文
  • libcurl 多线程使用注意事项

    万次阅读 2011-05-23 14:00:00
    1、问题来源,多线程使用Libcurl导致程序跑一段时间后自己退出,没有明显的异常。找不到合适的BUG。   最后通过查看资料和网上找的一些文章,发现,原来是信号处理的问题:     CURLOPT_NOSIGNAL Pass ...
  • 为了提高CPU的使用率,采用多线程的方式去同时完成几件事情而不互相干扰.为了处理大量的IO操作时或处理的情况需要花费大量的时间等等,比如:读写文件,视频图像的采集,处理,显示,保存等 多线程的好处: 1.使用线程可以...
  • 多线程编程中注意问题

    千次阅读 2012-10-18 10:13:45
    最近项目的多线程部分出了很多问题,导致程序出现了几个重大bug。 主要问题如下: 1. 两个线程的执行顺序,和代码的顺序不一定是完全一致的。一定做好同步。 2. 线程terminate的时候,如何获得了锁,记得...
  • wglMakeCurrent 多线程注意问题

    千次阅读 2016-09-10 13:06:19
    wglMakeCurrent wglMakeCurrent 函数设定OpenGL当前线程的...你也可以使用wglMakeCurrent 函数来改变调用线程的当前渲染环境,使之不再是当前的渲染环境。   BOOL wglMakeCurrent(  HDC hdc, // device context of
  • 什么多线程?如何实现多线程

    万次阅读 多人点赞 2019-04-09 09:53:36
    【转】什么线程安全?怎么实现线程安全?什么是进程?什么线程什么线程安全?添加一个状态呢?如何确保线程安全?synchronizedlock 转自:https://blog.csdn.net/csdnnews/article/details/82321777 什么是...
  • Qt多线程方法1 继承QThread 1写一个继承于QThread的线程 2 QThread的几个函数quitexitterminate函数 3 正确的终止一个线程 4 如何正确启动一个线程 41正确的启动一个全局线程和UI一直存在的线程 42 如何启动一...
  • 才想起来openssl是不支持多线程的,自己做加锁处理。而且libcurl中并没有支持相关的加锁操作。 解决办法: 在初始化libcurl的时候为openssl创建一个互斥锁函数,一个回调函数传给openss
  • 一、多线程使用情景: 1.用户需要同时得到多个反馈,例如下载过程中进度条改变,读取文件的时候显示结果。 2.提高程序执行性能,提高CPU使用效率,。 多线程的主要是需要处理大量的IO操作或者处理的情况需要花...
  • 万字图解Java多线程

    万次阅读 多人点赞 2020-09-06 14:45:07
    我以前也是感觉学会了,但是真正有多线程的需求却不知道怎么下手,实际上还是对多线程这块知识了解不深刻,不知道多线程api的应用场景,不知道多线程的运行流程等等,本篇文章将使用实例+图解+源码的方式来解析java...
  • JAVA多线程使用场景和注意事项

    千次阅读 2019-03-15 17:59:58
    我曾经对自己的小弟说,如果你实在搞不清楚什么时候用HashMap,什么时候用...多线程生来就是复杂的,也是容易出错的。一些难以理解的概念,规避。本文不讲基础知识,因为你手里就有jdk的源码。 线程 Threa...
  • 多线程开发中需要注意问题

    千次阅读 2017-03-21 23:04:34
    多线程开发在 Linux 平台上已经有成熟的 Pthread 库支持。其涉及的多线程开发的最基本概念主要包含三点:线程,互斥锁,条件。其中,线程操作又分线程的创建,退出,等待 3 种。互斥锁则包括 4 种操作,分别是创建,...
  • 多线程(一):创建线程和线程的常用方法

    万次阅读 多人点赞 2018-09-01 19:14:23
    一:为什么要多线程 应付面试 :多线程几乎是面试中必问的题,所以掌握一定的基础知识是必须的。 了解并发编程:实际工作中很少写多线程的代码,这部分代码一般都被人封装起来了,在业务中使用多线程的机会也...
  • SQLiteDatabase 多线程访问需要注意问题 1. 多线程打开SQLiteDatabase // Thread 1 Context context = getApplicationContext(); DatabaseHelper helper = new DatabaseHelper(context); SQLiteDatabase database ...
  • 多线程+Webservice分布式编程时需要注意的COM问题
  • 多线程编程注意事项

    千次阅读 2011-12-27 09:35:18
    背景 ...本文中我们从 5 个方面总结出 Linux 多线程编程上的问题,并分别引出相关改善的开发经验,用以避免这些的陷阱。我们希望这些经验可以帮助读者们能更好更快的熟悉 Linux 平台的多线程编程。
  • java 多线程注意事项

    千次阅读 2017-02-21 12:42:42
    少了浪费了系统资源,了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务...
  • 二、在多线程Thread下使用Delegate要注意 1、我们应该知道Monobehaviour提供的一些快捷的API去调用,例如:FindObjectOfType,GameObject.Find,SendMessage,StartCoroutine……等等。 如果在其他线程去调用这些...
  • MFC多线程编程注意事项

    万次阅读 热门讨论 2008-05-26 11:17:00
    MFC多线程编程注意事项PeterLee整理 2008-05-261. 表现——错误示例关于启动线程时传输窗口对象(指针?句柄?)的问题: 在选择菜单中的开始线程后: void cmainframe::onmenu_start() { ... afxbeginthread...
  • tomcat多线程处理及ThreadLocal使用注意

    千次阅读 2019-01-24 14:14:13
    tomcat多线程处理及ThreadLocal使用注意 tomcat默认使用线程池来管理线程,即当收到一个请求时,如果线程池存在空闲线程,则会从中取出一个空闲线程来处理该请求。当一个线程在处理请求时,其他请求就不会被分配至该...
  • 现在Qt官方并不是很推荐继承QThread来实现多线程方法,而是极力推崇继承QObject的方法来实现,当然用哪个方法实现视情况而定,别弄错了就行,估计Qt如此推崇继承QObject的方法可能是QThread太容易用错的原因。...
  • Java 多线程:彻底搞懂线程池

    万次阅读 多人点赞 2019-07-09 19:27:00
    熟悉Java多线程编程的同学都知道,当我们线程创建过多时,容易引发内存溢出,因此我们就有必要使用线程池的技术了。 目录 1 线程池的优势 2 线程池的使用 3 线程池的工作原理 4 线程池的参数 4.1 任务队列...
  • 多线程多进程数据库访问应注意问题:事务在执行时不知道其他事务的存在,无论是多Connection或是单Connection。1、Select 语句不需要显示的用 BeginTrans 声明事务。如果显示的进行了声明则会给数据库加入共享锁,接...
  • JAVA多线程常见的十大问题

    万次阅读 2020-05-06 20:55:40
    JAVA多线程常见的十大问题讲解
  • Java多线程

    万次阅读 多人点赞 2021-06-11 16:28:49
    Java多线程Java多线程线程的创建线程常见方法线程的状态线程的优先级守护线程线程组Java线程池线程池的创建线程池的参数线程池的使用线程不安全问题Java中的锁synchronized同步方法synchronized同步语句块...
  • 什么使用多线程?

    万次阅读 2008-04-05 00:09:00
    1.耗时的操作使用线程,提高应用程序响应2.并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。... 使用多线程的理由之一是和进程相比,它是一种非常花销小,切换快,更"节俭"的多任

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 949,671
精华内容 379,868
关键字:

使用多线程要注意什么问题