关于多线程的问题

问题描述

想实现a,b,c,d四个线程并行运行,要求d线程依赖于abc三个线程,abc三个线程执行完才能执行d线程,b线程依赖于c线程,c线程执行完才能执行b线程,以下是我写的代码,a、c线程执行完毕后就挂起了,不知道问题在哪儿,求指教package test.com.cn;public class ThreadTest{public static void main(String[] args) {Signal s = new Signal(); Runnable at = new MyThreadABC(s,"A");Runnable bt = new MyThreadABC(s,"B");Runnable ct = new MyThreadABC(s,"C");Runnable dt = new MyThreadD(s,"D");new Thread(at).start();new Thread(bt).start();new Thread(ct).start();new Thread(dt).start(); }}class Signal{//private boolean abcend;private Boolean bend = false;private Boolean cend = false;private Boolean aend = false;public boolean isAend() {return aend;}public void setAend(boolean aend) {this.aend = aend;}public boolean isBend() {return bend;}public void setBend(boolean bend) {this.bend = bend;}public synchronized boolean isCend() throws InterruptedException {synchronized (cend) {while(!cend){wait();}}notifyAll();return cend;}public synchronized void setCend(Boolean cend) {synchronized (cend) {this.cend = cend;}}//public boolean isDend() {//return dend;//}//public void setDend(boolean dend) {//this.dend = dend;//}//public synchronized boolean isAbcEnd() throws InterruptedException{synchronized(this){while(!(aend&&bend&&cend)){wait();}}notifyAll();return Boolean.valueOf(aend&&bend&&cend);} }class MyThreadABC implements Runnable{private Signal signal;private String tid;public String getTid() {return tid;}public void setTid(String tid) {this.tid = tid;}public Signal getSignal() {return signal;}public MyThreadABC(Signal signal,String tid) {this.signal = signal;this.tid = tid;}public void setSignal(Signal signal) {this.signal = signal;}public void run() {if(tid=="A")signal.setAend(true);try {if(tid=="B"&&signal.isCend())signal.setBend(true);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}if(tid=="C"){signal.setCend(true);}System.out.println("我是进程"+tid+",执行完毕");}}class MyThreadD implements Runnable{private Signal signal;private String tid;public String getTid() {return tid;}public void setTid(String tid) {this.tid = tid;}public Signal getSignal() {return signal;}public MyThreadD(Signal signal,String tid) {this.signal = signal;this.tid = tid;}public void setSignal(Signal signal) {this.signal = signal;} public void run() {try {if(signal.isAbcEnd()){ System.out.println("我是进程"+tid+",执行完毕");}} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}执行结果:我是进程A,执行完毕 我是进程C,执行完毕

解决方案

package test.thread.concurrent;import java.util.Random;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;import java.util.concurrent.TimeUnit;/** * @author yu <br/> * Created date: 2013-3-7 <br/> */public class CyclicBarrierTest { Thread a = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread A started..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread A starts waiting..."); waitAbc.await(); // waiting } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); Thread b = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread B started..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread B is waiting..."); waitAbc.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); Thread c = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread C started..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread C starts waiting..."); waitC.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); Thread d = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread D started..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread D ends.."); } catch (InterruptedException e) { e.printStackTrace(); } } }); // waiting c execute and execute b CyclicBarrier waitC = new CyclicBarrier(1, new Runnable() { @Override public void run() { System.out.println("Thread C ends, starting B..."); b.start(); } }); // waiting a,b(,c) execute d CyclicBarrier waitAbc = new CyclicBarrier(2, new Runnable() { @Override public void run() { System.out.println("Thread A, B, C ends, starting D..."); d.start(); } }); public static void main(String[] args) { CyclicBarrierTest test = new CyclicBarrierTest(); test.a.start(); test.c.start(); }}某一次的运行结果引用Thread A started...Thread C started...Thread A starts waiting...Thread C starts waiting...Thread C ends, starting B...Thread B started...Thread B is waiting...Thread A, B, C ends, starting D...Thread D started...Thread D ends..
解决方案二:
比如你的B线程执行到代码39行,然后停在那里等待了。但是没有其他线程能唤醒它,检查下代码吧。比如在setCend里面唤醒一下其他线程。自己再调调。加油!
解决方案三:
对于你这个例子,个人更偏好CountDownLatch, 反正两个例子都有了,你自己看package test.thread.concurrent;import java.util.Random;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;/** * @author yale.yu <br/> * Created date: 2013-3-7 <br/> */public class CountDownLatchTest { CountDownLatch lockC = new CountDownLatch(1); CountDownLatch lockABC = new CountDownLatch(3); Thread a = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread A executing..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread A starts executed..."); lockABC.countDown(); // change counter } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread b = new Thread(new Runnable() { @Override public void run() { try { lockC.await(); //waiting c System.out.println("Thread B executing..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread B is executed..."); lockABC.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread c = new Thread(new Runnable() { @Override public void run() { try { System.out.println("Thread C executing..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread C starts executed..."); lockC.countDown(); lockABC.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread d = new Thread(new Runnable() { @Override public void run() { try { lockABC.await(); //waiting a,b,c System.out.println("Thread D executing..."); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println("Thread D ends.."); } catch (InterruptedException e) { e.printStackTrace(); } } }); public static void main(String[] args) { CountDownLatchTest test = new CountDownLatchTest(); test.a.start(); test.b.start(); test.c.start(); test.d.start(); }}引用Thread A executing...Thread C executing...Thread A starts executed...Thread C starts executed...Thread B executing...Thread B is executed...Thread D executing...Thread D ends..
解决方案四:
代码没时间给你写,你去看看:java.util.concurrent.CyclicBarrier

时间: 2024-09-19 16:48:02

关于多线程的问题的相关文章

VB.NET多线程应用

开发者一直要求微软为VB加入更多的多线程功能,对于VB.NET也是这样.VB6已经支持建立多线程的EXE.DLL和OCX.不过使用多线程这个词语,可能也不太确切.因此VB6仅支持运行多个单线程的单元.一个单元实际上是代码执行的空间,而单元的边界限制了代码访问任何单元以外的事物. VB.NET就不同了,它支持建立自由线程(free-threaded)的应用.这意味着多个线程可以访问同样一套的共享数据.本文的以下部分将讨论一下多线程的一些基本点. 问题 虽然VB6支持多个单线程的单元,不过它并不支持

多线程中锁的实现.

*引用本文请注明来自 blog.csdn.net/wtz1985        所谓"锁",就是为了让自己独自占有空间,在自己没用完之前,不让别人来占用自己的资源.现在的操作系统,无论是WINDOWS,还是UNIX等其他操作系统.都采用多线程的环境.这极大提高了任务的执行速度,而且不会影响其他事务的执行.但是它们的执行是靠时间片的轮转的,如果某一个线程没有执行完,可它的时间片用完了,就会被挂起来,直到轮到它的下个时间片.假如继续让它们这么自由的,没有约束的执行命令,将会导致一种不可预见

Linux多线程之同步

引言 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待条件变量的条件成立而挂起(此时不再占用cpu):另一个线程使条件成立(给出条件成立信号).为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起. 函数原型 1. 定义条件变量 #include <pthread.h>/* 定义两个条件变量 */pthread_cond_t cond_pro, cond_con; 2. 初始化和销毁条件变量 #include <pthread.h>int pt

Java多线程基础总结八:ReentrantReadWriteLock

说到ReentrantReadWriteLock,首先要做的是与ReentrantLock划清界限.它和后者都是单独的实现,彼此之间没有继承或实现的关系. 然后就是总结这个锁机制的特性了: (a).重入方面其内部的WriteLock可以获取ReadLock,但是反过来ReadLock想要获得WriteLock则永远都不要想. (b).WriteLock可以降级为ReadLock,顺序是:先获得WriteLock再获得ReadLock,然后释放WriteLock,这时候线程将保持Readlock的

上下文切换与多线程实现的代价

多线程中的上下文切换 支持多任务处理是CPU设计史上最大的跨越之一.在计算机中,多任务处理是指同时运行两个或多个程序.从使用者的角度来看,这看起来并不复杂或者难以实现,但是它确实是计算机设计史上一次大的飞跃.在多任务处理系统中,CPU需要处理所有程序的操作,当用户来回切换它们时,需要记录这些程序执行到哪里.上下文切换就是这样一个过程,他允许CPU记录并恢复各种正在运行程序的状态,使它能够完成切换操作. 在上下文切换过程中,CPU会停止处理当前运行的程序,并保存当前程序运行的具体位置以便之后继续运

java多线程总结一:线程的两种创建方式及优劣比较

http://blog.csdn.net/touch_2011/article/details/6891026 1.通过实现Runnable接口线程创建 (1).定义一个类实现Runnable接口,重写接口中的run()方法.在run()方法中加入具体的任务代码或处理逻辑. (2).创建Runnable接口实现类的对象. (3).创建一个Thread类的对象,需要封装前面Runnable接口实现类的对象.(接口可以实现多继承) (4).调用Thread对象的start()方法,启动线程 示例代码

java单线程和多线程的区别

1.单线程和多线程的区别? 你早上上班,正要打卡的时候,手机响了..你如果先接了电话,等接完了,在打卡,就是单线程.如果你一手接电话,一手打卡.就是多线程.这两件事的结果是一样的..你接了电话且打了卡. (1)最常见的一个线程例子: package com.ggx.thread; public class OnlyThread{ public static void main(String[] args){ System.out.println("我就是一个线程"); } } 当程序启

(单例设计模式中)懒汉式与饿汉式在多线程中的不同

/*  目的:分析一下单例设计模式中,懒汉式与饿汉式在多线程中的不同!  开发时我们一般选择饿汉式,因为它简单明了,多线程中不会出现安全问题!  而饿汉式需要我们自己处理程序中存在的安全隐患,但是饿汉式的程序技术含量更高! */ /* class SinglePerson implements Runnable{    private static SinglePerson ss = new SinglePerson("hjz", 22);//恶汉式    private int ag

多线程-请教:关于RandomAccessFile阻塞ScheduledExecutorService的问题

问题描述 请教:关于RandomAccessFile阻塞ScheduledExecutorService的问题 大家好, 我想实现 读一个正在动态增长的日志 的功能,下面第一段代码本够用了,可惜 那个日志还会不定时自动 归档(滚动,也就是 .log 变 *.log1 .log1变 *.log2 ,类推) 已经打开的 RandomAccessFile 仍然盯着最早关联的文件,无法识别关联到新生成的 *.log 所以我修改了这段代码,就是下面第二段代码 新的问题是: 程序已运行到 randomFil

多线程-如何在OpenGL中渲染多个视频

问题描述 如何在OpenGL中渲染多个视频 程序使用win32开发,视频使用ffmpeg进行帧的截取,然后贴到OpenGL纹理中,渲染一个视频的话不用使用到多线程,处理能力足够快,但是现在需要渲染多个视频,不可能在主线程完成,两三个视频基本上窗口就卡死了.后来改用多线程,建立了两个OpenGL的上下文环境,一个线程负责更新纹理,主线程负责渲染,但是更新纹理的线程依然是照着视频一个个照顺序截,截完再通知主线程画出来,本来以为这样的结构应该没问题,结果渲染速度依然达不到要求,现在想问问有什么办法做到