Java 具有两个线程的IllegalMonitorStateException
我的程序有两个线程,每个线程打印十个数字。第一个线程打印奇数,第二个线程打印偶数,它们轮流打印数字。我希望在20之前得到一个像1,2,3,4,5…这样的序列,但是程序会产生一个非法的MonitorStateException 我知道这个异常意味着什么,但我在synchronized块中使用了Java 具有两个线程的IllegalMonitorStateException,java,multithreading,Java,Multithreading,我的程序有两个线程,每个线程打印十个数字。第一个线程打印奇数,第二个线程打印偶数,它们轮流打印数字。我希望在20之前得到一个像1,2,3,4,5…这样的序列,但是程序会产生一个非法的MonitorStateException 我知道这个异常意味着什么,但我在synchronized块中使用了wait()和notify()。这是我的密码: public class EvenOddThreadTest { /** * @param args */
wait()
和notify()
。这是我的密码:
public class EvenOddThreadTest {
/**
* @param args
*/
static Object obj1 = new Object();
static Object obj2 = new Object();
static Object obj3=new EvenOddThreadTest();
public static void main(String[] args) throws InterruptedException {
new Thread() {
@Override
public void run() {
for (int i = 1; i < 21; i += 2) {
synchronized (obj1) {
System.out.println(i + Thread.currentThread().getName());
try {
obj2.notify();
obj1.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
new Thread() {
@Override
public void run() {
for (int i = 2; i < 21; i += 2) {
synchronized (obj2) {
System.out.println(i + Thread.currentThread().getName());
try {
obj1.notify();
obj2.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}.start();
}
}
我想不出来。有什么想法吗?您不能对您没有监视器的对象调用notify:
synchronized (obj1) {
System.out.println(i + Thread.currentThread().getName());
try {
obj2.notify(); // You haven't synchronized on obj2
在线程0中,您仅在
obj2
上同步,而不是在调用notify
的obj1
上同步。在第二个线程中,情况正好相反 这并不能直接回答您的问题,但线程级别非常低。例如,在您的情况下,您可以使用,它将为您处理同步细节:
public class Test {
static CyclicBarrier barrier = new CyclicBarrier(2);
public static void main(String[] args) throws InterruptedException {
new Thread() {
@Override
public void run() {
try {
for (int i = 1; i < 21; i += 2) {
System.out.println(i + Thread.currentThread().getName());
barrier.await();
}
} catch (BrokenBarrierException e) {
//do something
} catch (InterruptedException e) {
//do something
}
}
}.start();
new Thread() {
@Override
public void run() {
try {
for (int i = 2; i < 21; i += 2) {
barrier.await();
System.out.println(i + Thread.currentThread().getName());
}
} catch (BrokenBarrierException e) {
//do something
} catch (InterruptedException e) {
//do something
}
}
}.start();
}
}
公共类测试{
静态循环载体屏障=新循环载体(2);
公共静态void main(字符串[]args)引发InterruptedException{
新线程(){
@凌驾
公开募捐{
试一试{
对于(int i=1;i<21;i+=2){
System.out.println(i+Thread.currentThread().getName());
障碍。等待();
}
}捕获(断线承运人例外){
//做点什么
}捕捉(中断异常e){
//做点什么
}
}
}.start();
新线程(){
@凌驾
公开募捐{
试一试{
对于(int i=2;i<21;i+=2){
障碍。等待();
System.out.println(i+Thread.currentThread().getName());
}
}捕获(断线承运人例外){
//做点什么
}捕捉(中断异常e){
//做点什么
}
}
}.start();
}
}
如果两个线程一起工作,则它们需要在同一个变量上同步。您希望一个线程等待轮到它运行,然后运行,然后通知另一个线程
public class EvenOddThreadTest {
/**
* @param args
*/
static Object obj1 = new Object();
static Object obj3=new EvenOddThreadTest();
public static void main(String[] args) throws InterruptedException {
new Thread() {
@Override
public void run() {
for (int i = 1; i < 21; i += 2) {
synchronized (obj1) {
try {
while (/* not my turn to run *?*/) {
obj1.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i + Thread.currentThread().getName());
obj1.notify();
}
}
}
}.start();
new Thread() {
@Override
public void run() {
for (int i = 2; i < 21; i += 2) {
synchronized (obj1) {
try {
while (/* not my turn to run *?*/) {
obj1.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i + Thread.currentThread().getName());
obj1.notify();
}
}
}
}.start();
}
}
公共类测试{
/**
*@param args
*/
静态对象obj1=新对象();
静态对象obj3=新的EvenOddThreadTest();
公共静态void main(字符串[]args)引发InterruptedException{
新线程(){
@凌驾
公开募捐{
对于(int i=1;i<21;i+=2){
已同步(obj1){
试一试{
而(/*不轮到我跑了*?*/){
obj1.wait();
}
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(i+Thread.currentThread().getName());
obj1.notify();
}
}
}
}.start();
新线程(){
@凌驾
公开募捐{
对于(int i=2;i<21;i+=2){
已同步(obj1){
试一试{
而(/*不轮到我跑了*?*/){
obj1.wait();
}
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(i+Thread.currentThread().getName());
obj1.notify();
}
}
}
}.start();
}
}
这不会控制谁先运行,只是确保两个线程在打印第二个数字之前都打印第一个数字。
public class EvenOddThreadTest {
/**
* @param args
*/
static Object obj1 = new Object();
static Object obj3=new EvenOddThreadTest();
public static void main(String[] args) throws InterruptedException {
new Thread() {
@Override
public void run() {
for (int i = 1; i < 21; i += 2) {
synchronized (obj1) {
try {
while (/* not my turn to run *?*/) {
obj1.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i + Thread.currentThread().getName());
obj1.notify();
}
}
}
}.start();
new Thread() {
@Override
public void run() {
for (int i = 2; i < 21; i += 2) {
synchronized (obj1) {
try {
while (/* not my turn to run *?*/) {
obj1.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i + Thread.currentThread().getName());
obj1.notify();
}
}
}
}.start();
}
}