//请问这二者有何区别??
class SellThread extends Thread
{
static Object obj=new Object();
static int tickets=50;
public void run()
{
while(tickets>0)
{
/*synchronized(obj)//线程同步块
{
if(tickets>0)
{
System.out.println(Thread.currentThread
().getName( )+" sell tickets:"+tickets);
tickets=tickets-1;
try
{
Thread.sleep(1);
}
catch(Exception e)
{
e.printStackTrace();
}
}*/
sell();
}
}
public synchronized void sell()//线程同步方法
{
if(tickets>0)
{
System.out.println(Thread.currentThread().getName( )+" sell
tickets:"+tickets);
tickets--;
}
}
}
class TicketsSystem_this_obj
{
public static void main(String args[])
{
SellThread st1=new SellThread();
SellThread st2=new SellThread();
SellThread st3=new SellThread();
SellThread st4=new SellThread();
st1.start();
st2.start();
st3.start();
st4.start();
/* try
{
Thread.sleep(10);
}
catch(Exception e)
{
e.printStackTrace();
}*/
}
}
4 个解决方案
#1
这样子的sell不是每个线程各自的sell么?
不是多个现成调用同一个sell,如果是static的sell方法那才是多个线程调用同一个sell方法synchronized才有效果
我也不是很懂,但是好像是这样的
不是多个现成调用同一个sell,如果是static的sell方法那才是多个线程调用同一个sell方法synchronized才有效果
我也不是很懂,但是好像是这样的
#2
一个类只能有一个父类,就是单继承。如果这个类已经有父类,就只能通过实现接口来实现了。
#3
参考楼上的。
#4
1、由于java的单继承机制,你继承Thread类的话,那么这个自定义线程类就不能再继承其它的类;而接口可以实现多个,所以通过实现Runnable接口来实现的话,那么这个实现类还可以继承其它的类
2、同步方法和同步块都是通过同步监视器来实现同步的,只不过同步块可以自己指定同步监视器,而同步方法使用默认的监视器,即该方法当前所在对象的引用(this);
st1、st2、st3、st4中的同步块用的监视器都是static Object obj=new Object();因为该静态变量对SellThread类的所有实例来说都是一样的,所以它们可以实现同步;
但st1、st2、st3、st4四个 实例中的sell()方法用的同步监视器分别是st1、st2、st3、st4,所以无法同步
可以照下面参考下:
2、同步方法和同步块都是通过同步监视器来实现同步的,只不过同步块可以自己指定同步监视器,而同步方法使用默认的监视器,即该方法当前所在对象的引用(this);
st1、st2、st3、st4中的同步块用的监视器都是static Object obj=new Object();因为该静态变量对SellThread类的所有实例来说都是一样的,所以它们可以实现同步;
但st1、st2、st3、st4四个 实例中的sell()方法用的同步监视器分别是st1、st2、st3、st4,所以无法同步
可以照下面参考下:
package Lesson8;
class SellThread extends Thread {
private Tickets tickets;
public SellThread(Tickets tickets)
{
this.tickets=tickets;
}
public void run() {
while (tickets.getNum()>0) {
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
tickets.sell();
}
}
}
public class Demo3 {
public static void main(String args[]) {
Tickets tickets=new Tickets(20);
SellThread st1 = new SellThread(tickets);
SellThread st2 = new SellThread(tickets);
SellThread st3 = new SellThread(tickets);
SellThread st4 = new SellThread(tickets);
st1.start();
st2.start();
st3.start();
st4.start();
}
}
class Tickets
{
private int num=0;
public int getNum()
{
return num;
}
public Tickets(int num)
{
this.num=num;
}
public synchronized void sell()// 线程同步方法
{
if (num > 0) {
System.out.println(Thread.currentThread().getName()
+ " sell tickets:" + num);
num--;
}
}
}
#1
这样子的sell不是每个线程各自的sell么?
不是多个现成调用同一个sell,如果是static的sell方法那才是多个线程调用同一个sell方法synchronized才有效果
我也不是很懂,但是好像是这样的
不是多个现成调用同一个sell,如果是static的sell方法那才是多个线程调用同一个sell方法synchronized才有效果
我也不是很懂,但是好像是这样的
#2
一个类只能有一个父类,就是单继承。如果这个类已经有父类,就只能通过实现接口来实现了。
#3
参考楼上的。
#4
1、由于java的单继承机制,你继承Thread类的话,那么这个自定义线程类就不能再继承其它的类;而接口可以实现多个,所以通过实现Runnable接口来实现的话,那么这个实现类还可以继承其它的类
2、同步方法和同步块都是通过同步监视器来实现同步的,只不过同步块可以自己指定同步监视器,而同步方法使用默认的监视器,即该方法当前所在对象的引用(this);
st1、st2、st3、st4中的同步块用的监视器都是static Object obj=new Object();因为该静态变量对SellThread类的所有实例来说都是一样的,所以它们可以实现同步;
但st1、st2、st3、st4四个 实例中的sell()方法用的同步监视器分别是st1、st2、st3、st4,所以无法同步
可以照下面参考下:
2、同步方法和同步块都是通过同步监视器来实现同步的,只不过同步块可以自己指定同步监视器,而同步方法使用默认的监视器,即该方法当前所在对象的引用(this);
st1、st2、st3、st4中的同步块用的监视器都是static Object obj=new Object();因为该静态变量对SellThread类的所有实例来说都是一样的,所以它们可以实现同步;
但st1、st2、st3、st4四个 实例中的sell()方法用的同步监视器分别是st1、st2、st3、st4,所以无法同步
可以照下面参考下:
package Lesson8;
class SellThread extends Thread {
private Tickets tickets;
public SellThread(Tickets tickets)
{
this.tickets=tickets;
}
public void run() {
while (tickets.getNum()>0) {
try {
sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
tickets.sell();
}
}
}
public class Demo3 {
public static void main(String args[]) {
Tickets tickets=new Tickets(20);
SellThread st1 = new SellThread(tickets);
SellThread st2 = new SellThread(tickets);
SellThread st3 = new SellThread(tickets);
SellThread st4 = new SellThread(tickets);
st1.start();
st2.start();
st3.start();
st4.start();
}
}
class Tickets
{
private int num=0;
public int getNum()
{
return num;
}
public Tickets(int num)
{
this.num=num;
}
public synchronized void sell()// 线程同步方法
{
if (num > 0) {
System.out.println(Thread.currentThread().getName()
+ " sell tickets:" + num);
num--;
}
}
}