我有以下用例。假设它可以在JAVA 6上运行,任何人都可以建议方法 t1()的良好实现吗?我试着想到使用wait()和notify()完成这个,但无法得到正确的解决方案。任何帮助将不胜感激。 (请注意,这两种方法 t1()和 m1()都将在不同的线程中调用)
class Test
{
static volatile int flag = 0;
public static void t1()
{
//This method will be called in a Thread called T2
/*This method must wait for flag to become 1. As soon it
becomes 1 this must return. However it should wait for maximum
n seconds. After that even if flag is 0 it must return.*/
}
public static void m1()
{
//This method will be called in a Thread called T1
flag = 1;
}
}
这就是我尝试t1()
的实现 public static void t1() throws InterruptedException
{
while(flag == 0)
{
Thread.currentThread().sleep(100);
}
}
以上工作但问题是超时没有实现,而循环似乎没那么好。
答案 0 :(得分:3)
使用CountDownLatch
。在使用count计数运行的任何线程之前初始化它。您的代码将如下所示:
class Test
{
static CountDownLatch latch = new CountDownLatch(1);
public static void t1()
{
//This method will be called in a Thread called T2
/*This method must wait for flag to become 1. As soon it
becomes 1 this must return. However it should wait for maximum
n seconds. After that even if flag is 0 it must return.*/
latch.await(1L,TimeUnit.SECONDS);
//your remaining logic
}
public static void m1()
{
//your logic
latch.countDown();
}
}
CountDownLatch
是一个有点修改,增强(例如超时选项),可以说更容易理解Semaphore的实现 - 一种广泛用于跨数字线程同步的基本结构语言(不仅是Java)。在比较Wikipedia对Java实现的引用时请注意以下内容:
P
/ wait()
对应await()
,区别在于await()
不会更改count
值。V
/ signal()
对应countDown()
,区别在于countDown()
计数向下,而不是向上(显然)。答案 1 :(得分:2)
使用CountDownLatch
private static CountDownLatch countDownLatch = new CountDownLatch(1);
public static void t1() throws InterruptedException {
countDownLatch.await(1000L, TimeUnit.MILLISECONDS);
System.out.println("t2");
}
public static void m1() throws InterruptedException {
System.out.println("t1");
// you can simulate some activity
Thread.sleep(500);
countDownLatch.countDown();
}
运行t1()
的线程必须等待一秒钟。
public static void main(String[] args) throws IOException, ParseException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
test.Test.m1();
} catch (InterruptedException e) {
// do something
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
test.Test.t1();
} catch (InterruptedException e) {
// do something
}
}
});
t2.start();
t1.start();
}
这在静态上下文中是一个坏主意,但是因为其他类可以访问它并且可能调用方法,这会搞砸锁。
答案 2 :(得分:0)
您可以投票,直到条件满足为止。我认为使用Thread.sleep(long time)
更实际,而不是在检查之间使用Thread.yield()
:
public static void t1()
{
while (flag == 0)
{
Thread.yield();
}
}
答案 3 :(得分:0)
使用CountDownLatch
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class Race {
public static void main(String[] args) {
boolean flag=true; //set false to see other behavior
if (flag) {
startRace(5L, 2L);
} else {
startRace(2L, 5L);
}
}
private static void startRace(final long s1, final long s2) {
new Thread() {
@Override
public void run() {
Test.t1(s1);
}
}.start();
new Thread() {
@Override
public void run() {
Test.t2(s2);
}
}.start();
}
}
class Test {
static volatile int flag = 0;
static CountDownLatch L = new CountDownLatch(1);
public static void t1(long n) {
await(n);
logic1();
L.countDown(); // comment to wait till end
}
public static void t2(long n) {
await(n);
logic2();
L.countDown();
}
private static void logic1() {
if (flag == 0) {
System.out.println(Thread.currentThread()
+ ": Flag Couldnt be set in time");
} else {
System.out.println(Thread.currentThread() + ": Flag set in time");
}
}
private static void logic2() {
flag = 1;
System.out.println(Thread.currentThread() + ": Flag Set");
}
private static void await(long n) {
waitMsg(n);
try {
if (L.await(n, TimeUnit.SECONDS)) {
waitOverBefore(n);
} else {
waitOver(n);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void waitOverBefore(long n) {
System.out.println(Thread.currentThread() + ": Waiting Over before "
+ n + " seconds");
}
private static void waitOver(long n) {
System.out.println(Thread.currentThread() + ":" + n
+ " seconds Waiting Over");
}
private static void waitMsg(long n) {
System.out.println(Thread.currentThread() + ":Waiting for " + n
+ " seconds");
}
}
输出1
Thread[Thread-0,5,main]:Waiting for 5 seconds
Thread[Thread-1,5,main]:Waiting for 2 seconds
Thread[Thread-1,5,main]:2 seconds Waiting Over
Thread[Thread-1,5,main]: Flag Set
Thread[Thread-0,5,main]: Waiting Over before 5 seconds
Thread[Thread-0,5,main]: Flag set in time
输出2
Thread[Thread-1,5,main]:Waiting for 5 seconds
Thread[Thread-0,5,main]:Waiting for 2 seconds
Thread[Thread-0,5,main]:2 seconds Waiting Over
Thread[Thread-0,5,main]: Flag Couldnt be set in time
Thread[Thread-1,5,main]: Waiting Over before 5 seconds
Thread[Thread-1,5,main]: Flag Set