Java 同一线程能够在同一对象上执行两个同步方法
正如我所知,同一块上的同步方法只能执行一个线程,但在下面的生产者-消费者问题中,我能够运行这两个方法 示例代码Java 同一线程能够在同一对象上执行两个同步方法,java,multithreading,synchronization,Java,Multithreading,Synchronization,正如我所知,同一块上的同步方法只能执行一个线程,但在下面的生产者-消费者问题中,我能够运行这两个方法 示例代码 import java.util.concurrent.CountDownLatch; public class VIV { public static void main(String[] args) throws Exception { Number no = new Number(); //Same Object is passed
import java.util.concurrent.CountDownLatch;
public class VIV {
public static void main(String[] args) throws Exception {
Number no = new Number();
//Same Object is passed
Even ev = new Even(no, 10);
Odd od = new Odd(no, 10);
Thread oddThraed = new Thread(od,"ODD");
oddThraed.start();
Thread evenThraed = new Thread(ev,"Even");
evenThraed.start();
}
}
class Number {
int no;
boolean flag=false;
public synchronized int getEvenNo() {
System.out.println("In Even Method");
// wait block so no other thread can enter on same object synchronized method
try{
wait();
}catch (Exception e) {
// TODO: handle exception
}
if(!flag) {
try {
Thread.sleep(1000);
}catch (Exception e) {
// TODO: handle exception
}
}
no=no+1;
System.out.println(Thread.currentThread().getName()+":"+no);
flag=false;
notify();
return no;
}
public synchronized int getOddNo() {
System.out.println("In ODD Method");
// wait block so no other thread can enter on same object synchronized method
try{
wait();
}catch (Exception e) {
// TODO: handle exception
}
if(flag) {
try{
wait();
}catch (Exception e) {
// TODO: handle exception
}
}
no = no+1;
System.out.println(Thread.currentThread().getName()+":"+no);
flag=true;
notify();
return no;
}
}
class Even implements Runnable {
Number num;
int noOfTime;
Even(Number no, int noOfTime) {
this.num=no;
this.noOfTime=noOfTime;
}
public void run() {
for(int i=0;i<noOfTime;i++) {
num.getEvenNo();
}
}
}
class Odd implements Runnable {
Number num;
int noOfTime;
Odd(Number no, int noOfTime) {
this.num=no;
this.noOfTime=noOfTime;
}
public void run() {
for(int i=0;i<noOfTime;i++) {
num.getOddNo();
}
}
}
import java.util.concurrent.CountDownLatch;
公共类VIV{
公共静态void main(字符串[]args)引发异常{
编号编号=新编号();
//传递相同的对象
偶数ev=新偶数(编号10);
奇数od=新的奇数(编号10);
螺纹ODDSHREAD=新螺纹(外径,“奇数”);
oddsraed.start();
线程evenThraed=新线程(ev,“偶数”);
evenThraed.start();
}
}
班号{
国际贸易编号;
布尔标志=假;
公共同步int getEvenNo(){
System.out.println(“偶数法”);
//等待块,以便其他线程不能进入同一对象同步方法
试一试{
等待();
}捕获(例外e){
//TODO:处理异常
}
如果(!标志){
试一试{
睡眠(1000);
}捕获(例外e){
//TODO:处理异常
}
}
no=no+1;
System.out.println(Thread.currentThread().getName()+“:”+否);
flag=false;
通知();
返回否;
}
公共同步int getOddNo(){
System.out.println(“奇数法”);
//等待块,以便其他线程不能进入同一对象同步方法
试一试{
等待();
}捕获(例外e){
//TODO:处理异常
}
国际单项体育联合会(旗){
试一试{
等待();
}捕获(例外e){
//TODO:处理异常
}
}
no=no+1;
System.out.println(Thread.currentThread().getName()+“:”+否);
flag=true;
通知();
返回否;
}
}
类甚至实现了可运行的{
数字;
午休时间;
偶数(数字编号,int noOfTime){
this.num=no;
this.noOfTime=noOfTime;
}
公开募捐{
对于(int i=0;i两个方法同时执行的原因是wait()
method释放锁
,锁被返回,另一个线程可以在同一对象上调用另一个同步的
方法。不要以这种方式在同步的
方法中调用等待()
wait()
调用也是导致死锁的原因。发生的情况如下:
odd
方法获取锁并开始执行
odd
方法打印其第一条消息
odd
方法调用wait()
,释放锁并等待通知
甚至
方法现在可以获取已释放的锁
even
方法打印第一条消息
even
方法调用wait()
,释放锁并等待通知
这一点,你在<<代码>同步的方法中(因为<代码> WAITE)(/COD>释放锁),并且死锁(因为两种方法都在等待)。
不要调用
wait()
相反,它将暂停而不释放任何锁。通常只要将相关方法或块声明为已同步即可,无需任何等待
/通知
(顺便说一句,使用名为Number
的类不是一个好主意,因为这是一个标准的JDK类。它是Double
、Integer
等的超类。)两个方法同时执行的原因是等待()
method释放锁。一旦您的synchronized
方法调用wait()
,锁就会返回,另一个线程可以调用同一对象上的另一个synchronized
方法。不要以这种方式在synchronized
方法中调用wait()
wait()
调用也是导致死锁的原因。发生的情况如下:
odd
方法获取锁并开始执行
odd
方法打印其第一条消息
odd
方法调用wait()
,释放锁并等待通知
甚至
方法现在可以获取已释放的锁
even
方法打印第一条消息
even
方法调用wait()
,释放锁并等待通知
这一点,你在<<代码>同步的方法中(因为<代码> WAITE)(/COD>释放锁),并且死锁(因为两种方法都在等待)。
不要调用
wait()
相反,它将暂停而不释放任何锁。通常只要将相关方法或块声明为已同步即可,无需任何等待
/通知
(顺便说一句,有一个名为Number
的类不是一个好主意,因为这是一个标准的JDK类。它是Double
,Integer
,等等的超类。)我不知道你是否在尝试实现这种事情,如果你
public class VIV {
public static void main(String[] args) throws Exception {
TestNumber no = new TestNumber();
// Same Object is passed
Even ev = new Even(no, 10);
Odd od = new Odd(no, 10);
Thread oddThraed = new Thread(od, "ODD");
oddThraed.start();
Thread evenThraed = new Thread(ev, "Even");
evenThraed.start();
}
}
class TestNumber {
int no;
boolean flag = false;
public synchronized int getEvenNo() {
System.out.println("In Even Method");
// wait block so no other thread can enter on same object synchronized
// method
no = no + 1;
System.out.println(Thread.currentThread().getName() + ":" + no);
flag = false;
notify();
try {
wait();
} catch (Exception e) {
// TODO: handle exception
}
if (!flag) {
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
}
return no;
}
public synchronized int getOddNo() {
System.out.println("In ODD Method");
no = no + 1;
System.out.println(Thread.currentThread().getName() + ":" + no);
flag = true;
notify();
// wait block so no other thread can enter on same object synchronized
// method
try {
wait();
} catch (Exception e) {
// TODO: handle exception
}
if (flag) {
try {
wait();
} catch (Exception e) {
// TODO: handle exception
}
}
return no;
}
}
class Even implements Runnable {
TestNumber num;
int noOfTime;
Even(TestNumber no, int noOfTime) {
this.num = no;
this.noOfTime = noOfTime;
}
public void run() {
for (int i = 0; i < noOfTime; i++) {
num.getEvenNo();
}
}
}
class Odd implements Runnable {
TestNumber num;
int noOfTime;
Odd(TestNumber no, int noOfTime) {
this.num = no;
this.noOfTime = noOfTime;
}
public void run() {
for (int i = 0; i < noOfTime; i++) {
num.getOddNo();
}
}
}
In ODD Method
ODD:1
In Even Method
Even:2
In ODD Method
ODD:3
In Even Method
Even:4
In ODD Method
ODD:5
In Even Method
Even:6
In ODD Method
ODD:7
In Even Method
Even:8
In ODD Method
ODD:9
In Even Method
Even:10
In ODD Method
ODD:11
In Even Method
Even:12
In ODD Method
ODD:13
In Even Method
Even:14
In ODD Method
ODD:15
In Even Method
Even:16
In ODD Method
ODD:17
In Even Method
Even:18
In ODD Method
ODD:19
In Even Method
Even:20