java中关于线程的知识点和四个程序

来源:互联网 发布:java web架构设计 编辑:程序博客网 时间:2024/05/16 23:38

1.java中多线程同步是什么?
答:java中的线程程同步,是为了实现对共享资源的访问,如果没有过线程程同步机制,则会导致,当
某个线程在修改某个共享变量时,另一个线程程同时正在使用或更新同一个共享变量就会导致程序出错

2.线程有几种有哪些实现方法?
答:有两种:第一种通过继承Thread类,但这种方式只能单继承,第二种方法,通过继承Runnable类,这样可以
实现多继承。

3.Thread.start()和Thread.run()有什么区别?
答:Thread.start()方法是启动线程的,通过调用它,使线程进入就绪状态,当处于就绪状态的进程获得CPU后,
JVM会自动调用Thread.run()方法,使进程进入运行状态。

4.为什么需要run()和start()方法,我们可以只用run()方法来完成任务吗?
答:因为j由java创建一个单独的线程不同于其他方法的调用,这项工作由java的start()方法来
实现,另一个好处就是任何一个对象都可以作为进程运行,只要继承了runnable()方法,这就避免了因为
继承了Thread类而造成的多继承问题。

5.sleep(),suspend()和wait()有什么区别?
答:sleep(mills)方法使进程处于睡眠mills(s),在这段时间内进程处于非运行状态,线程一直持有
对象的监视器。sleep()方法是一个静态方法,只对当前进程有效;suspend()方法,也是使
进程进入阻塞状态,其他进程调用resume方法可将其唤醒,使用suspend()方法,容易造成死锁问题
wait(mills)使进程进入阻塞状态,在mills(s)内可由其他进程调用notity()方法将其唤醒,sleep()方法
和wait()方法的区别在于,sleep()方法是进程调用的,而wait()方法是对象调用的。

6.当一个同步方法已经执行,线程能调用对象上的非同步实例吗?
答:可以的,一个非同步方法总是可以被调用的。同步方法:synchronized修饰,把访问临界区的方法
定义为同步方法,java中没有对非同步方法做任何检查,锁对象仅仅会检查同步方法。

7.在一个对象上两个进程可以调用两个不同的同步实例方法吗?
答:不能,因为,当一个进程同步实例后,便获得了该进程的对象锁,只有在该进程的对象锁释放后
才能执行其他同步方法。

8.什么事死锁?
答:死锁就是两个或两个以上的进程无限的阻塞,一直相互等待所需资源。

9.进程和线程有什么区别?
答:进程是一个具有独立运行功能的程序关于某个数据集合的一次活动,是动态的,一个进程包含了多个线程,
进程是资源分配的最小单位,线程是独立运行和独立调度的基本单位,不同的进程拥有不同的内存空间,多个线程
利用相同的数据空间,每个线程都有单的的栈内存来存储本地数据。

10.什么事线程安全,Vector是一个线程安全类吗?
答:如果一个进程中有多个线程,多个线程同时运行这段代码,如果每次运行的结果和单线程运行的结果是一样的,
而且其他变量的值也都是和预期 的是一样的,那么就是线程安全的。Vector是线程安全的类。

11.java中如何停止一个线程?
答:java中并没用提供停止线程的API,像stop(),wait()等操作容易造成死锁问题,解决的方法就是在run()方法里设计
循环,利用boolean变量作为条件跳出循环结束线程,或者取消任务,不然只能等待进程执行结束。

12.java中notify()和notifyAll()有什么区别?notifyAll()
答:notify()不能唤醒某个指定等待的线程,所以只能用于只有一个等待进程的情况下,而notifyAll()唤醒所有
进程并允许他们抢锁确保了至少有一个进程能继续运行。

13.为什么notify和wait方法要在同步块中调用?
答:主要是因为Java API强制要求这样做,如果你不这么做,你的代码会抛出IllegalMonitorStateException异常。
还有一个原因是为了避免wait和notify之间产生竞态条件。

14.什么是线程池?为什么要调用它?
答:线程的创建时花费大量的资源和时间,如果等任务来了再创建的话响应的时间会比较长,而且一个进程能够创建的线程
数量是有限的,为了解决这个问题,在程序一开始执行的时候,便创建若干个线程响应处理,被称为线程池。利用Excutor框架可以,
不同的线程池。

15.如何写代码实现生产者消费者问题?
答:后面代码有答案

16.如何避免死锁?
答:进程造成死锁的必要条件为:互斥条件,请求和保持条件,不剥夺条件,循环等待条件,因此要避免死锁,就要破坏这些条件
中的一个,然而互斥条件是进程必须的,所以的破坏后三个条件,最简单的方法就是破坏循环等待条件。

17.线程中的yield方法有什么用?
答:当线程执行yield方法后,便放弃了对CPU的占用权。

18.java怎样唤醒一个阻塞的进程?
答:wait()方法导致阻塞,利用Notify()或notifyAll()方法来唤醒;
 sleep方法阻塞,在睡眠mills(s)重新进入就绪状态;
 susPend方法阻塞,利用resume()方法唤醒。
 
程序题-----------------------------------------------------------------------
第一题:-------------------------------------------------------------------
写两个线程,一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。
要求用线程间的通信。
package 作业;
class Thread1 extends Thread{
 public  void run(){
  try{
   Thread.sleep(1000);
  for(int i=1;i<=52;i++)
  {
   System.out.print(i);
   Thread.sleep(1000);
  }
  }
  catch(Exception e){
   System.out.println("线程错误:"+e);
  }
  
 }
}
class Thread2 extends Thread{
 public void run(){
  try{
   Thread.sleep(2000);
  for(char j='A';j<='Z';j++){
   
   System.out.print(j);
   Thread.sleep(2000);
   
  }
  }
  catch(Exception e){
   System.out.println("线程错误:"+e);
  }
 }
}
public class First {

 public static void main(String[] args) {
  Thread1 Th1=new Thread1();
  Th1.start();
  Thread2 Th2=new Thread2();
  Th2.start();
  

 }

}
第二题-------------------------------------------------------------------
生产者消费者问题编程,用同步机制实现
package 作业;
class HoldInt{
 private int sharedInt;
 private boolean writeAble=true;
 public synchronized void set(int val){
  while(!writeAble){
   try{
    wait();
   }
   catch(InterruptedException e){
   }
  }
  sharedInt=val;
  writeAble=false;
  notify();
 }
 public synchronized int  get(){
  while(writeAble){
   try{
    wait();
   }
   catch(InterruptedException e){
   }
  }
  writeAble=true;
  return sharedInt;
 }
}
class ProduceInt extends Thread{
 private HoldInt hi;
 public ProduceInt(HoldInt Hi){
  hi=Hi;
 }
 public void run(){
  for(int i=1;i<=4;i++){
   hi.set(i);
   System.out.println("生产者生产的数是:"+i);
  }
 }
}
class ConsumeInt extends Thread{
 private HoldInt hi;
 public ConsumeInt(HoldInt Hi){
  hi=Hi;
 }
 public void run(){
 for(int i=1;i<=4;i++){
  int val=hi.get();
  System.out.println("消费者读到的数是:"+val);
 }
 }
}
public class Second {

 public static void main(String[] args) {
  
  HoldInt h=new HoldInt();
  ProduceInt p=new ProduceInt(h);
  ConsumeInt c=new ConsumeInt(h);
  p.start();
  c.start();

 }

}
第三题:-------------------------------------------------------------------
请编写一个类,类名为 Sub Thread,  是 Thread 类的子类。该类中定义了 含一个字符串参数的构造方法和 run()方法,
方法中有一个 for循环,循环一共 进行5次,循环体先在命令行显示该线程循环了第几次,然后随机休眠小于一秒 的时间,
循环结束后显示线程结束信息:线程名+finished  。
package 作业;

class  A extends Thread{
 private String name;
 public  A(String Name){
  name=Name;
 }
 public void run(){
  int count=0;
  try{
  for(int i=1;i<=5;i++){
   System.out.println("循环体执行了第"+i+"次");
   count++;
   subThread.sleep(1000);
   if(count==5){
    System.out.println(name+"  Finshed");
   }
  }
  }
  catch(InterruptedException e){
   
  }
 }
}
public class Third{
 public static void main(String[] args) {
  A thread1=new A("A线程");
  thread1.start();
 }

}
第四题:------------------------------------------------------------------
(4)模拟3个人排除买票,张某、李某和赵某买
电影票,售票员只有3张五元的钱,电影票5元一张。张某拿20元一张的RMB排在李某的前面,
李某排在赵某的前面拿一张10元的RMB买票,赵某拿一张5元的RMB买票。
package 作业;
class HoldInt1{
 private int value=3;  //服务员手里有3个五块
 public synchronized void judge(String name,int inPut){
  
 while(inPut/5-1-value>0&&inPut/5!=1){        // 如果你手里的五块个数减去买票的五块大于服务员手里的五块个数,且你拿的不是五块
  try{
   System.out.println("不够找钱  "+name+"  等待");
   wait();
  }
  catch(InterruptedException e){
  }
 }
 if(inPut/5==1){                 //如果你拿的是五块
  value++;
  System.out.println(name+"购买成功,不找钱"+"服务员还有"+value+"个五块");
  notify();
 }
 else{                           //你拿的不是五块
  value=inPut/5-value-1;
  System.out.println(name+"购买成功,找 零:"+(inPut-5)+"服务员还有"+value+"个五块");
  notify();
 }
 }
}
class Student extends Thread{
 private HoldInt1 h1;
 String name;
 int inPut;
 public Student(String Name,int InPut,HoldInt1 hifrom){
  name=Name;
  inPut=InPut;
  h1=hifrom;
  }
 public void run(){
  h1.judge(name,inPut);
 }
}

public class Four {

 public static void main(String[] args) {
  HoldInt1 h=new HoldInt1();
  Student    A1=new Student("张某",20,h);
  Student    A2=new Student("李某",10,h);
  Student    A3=new Student("赵某",5,h);
     A1.start();
     A2.start();
     A3.start();
 }

}

0 0
原创粉丝点击