线程和进程

一,线程和进程的概念

线程是程序执行中的单个顺序流程,而进程就是一个执行中的程序,是操作系统对其资源进行分配的基本单位,没一个进程都有自己独立的一段内存空间,其内部数据和状态都是独立的。
需要注意的是:线程存在与进程之中,一个进程中的多个线程共享本进程的资源。

二,java如何启动线程?

j ava产生线程有两种办法:一种是继承Thread类,且覆盖其run()方法;另一种就是实现Runnable接口,并将实现类对象作为参数传递给Thread的构造方法。
l列出两种方法在main中的声明助大家区分:
(1)MyThread类通过继承thread类创建线程
Thread  a = new MyThread();
a.start();
(2)MyThread类通过继承Runnable接口创建线程
MyThread my=new MyThread();
Thread a=new Thread(my);
a.start();

三,线程的生命周期及线程状态的改变

   线程有5状态:创建,可执行,运行中,阻塞和死亡。其中,利用start()方法启动线程,当线程到达run()方法末尾的时或者线程抛出一个未捕获到的异常或错误的时候线程结束。

 作业:   

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.   写两个线程,一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。要求用线程间的通信。

public class Thread1 extends Thread{
private Object obj;
public Thread1(Object obj){
this.obj=obj;
}
public void run(){
synchronized(obj){
for(int i=1;i<53;i++){
System.out.print(i+"");
if(i%2==0){
obj.notifyAll();
try
{
obj.wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
}

public class Thread2 extends Thread{
private Object obj;
public Thread2(Object obj){
this.obj=obj;
}
public void run(){
synchronized(obj){
for(int i=0;i<26;i++){
System.out.print((char)('A'+i)+"");
obj.notifyAll();
try{
if(i!=25){
obj.wait();
}
}
catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
}

public class TestThread {


public static void main(String[] args) {
// TODO 自动生成的方法存根
Object obj=new Object();
Thread1 t1=new Thread1(obj);
Thread2 t2=new Thread2(obj);
t1.start();
t2.start();
}

}

2.   生产者消费者问题编程,用同步机制实现

public class buyer implements Runnable{
private product p1;
public buyer(product p1){
this.p1=p1;
}
public void run(){
while(true){
p1.get(80);
}
}
}

public class salor implements Runnable{
private product p1;
public salor(product p1){
this.p1=p1;
}
public void run(){
while(true){
p1.put(100);
}
}
}

public class product {
volatile private int num;
volatile private boolean isProduct=false;
public product(){
this.num=num;
}
synchronized void put(int n){
if(isProduct){
try{wait();}
catch(Exception e){}
}
num=num+n;
System.out.println("上货数量为:"+n+"当前产品的数量为:"+num);
isProduct=true;
notifyAll();
}
synchronized int get(int n){
if(!isProduct){
try{wait();}
catch(Exception e){}
}
if(num>n)
{num=num-n;}
else{n=num;num=0;}
System.out.println("卖出数量为:"+n+"当前产品的数量为:"+num);
isProduct=false;
notifyAll();
return n;
}
}

public class sell {


public static void main(String[] args) {
// TODO 自动生成的方法存根
product p1 = new product();
new Thread(new salor(p1)).start();
new Thread(new buyer(p1)).start();
}


}

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

public class SubThread extends Thread{
private String name;
public SubThread(String n){
name=n;
}
public void run(){
for(int i=0;i<5;i++){
System.out.println("该线程循环第"+(i+1)+"次");
try{
          Thread.sleep(1);
         }
     catch(InterruptedException e){
         System.exit(1);
      }       
}
System.out.println(name+ "finished");
    }
public static void main(String[] args) {
// TODO 自动生成的方法存根
    SubThread s=new SubThread("灰姑娘");
    s.start(); 
    
}
}

4.   模拟 3 个人排除买票,张某、李某和赵某买电影票,售票员只有 3 张五元的钱,电影票 5 元一张。张某拿 20 元一张的 RMB 排在李某的前面,李某排在赵某的前面拿一张 10 元的 RMB 买票,赵某拿一张 5 元的 RMB 买票。
   public class shoupiao implements Runnable{
    public void run() {
        String name = Thread.currentThread().getName();
        if (name.equals("w")) {
            System.out.println("您给我20元。找您15元。");
        } if (name.equals("l")) {
            System.out.println("您给我10元,找您5元");
        } 
        else if (name.equals("z")) {
        System.out.println("您给我5元,刚刚好");
            }
        }
    }  

    public class moni {


public static void main(String[] args) {
// TODO 自动生成的方法存根
Thread 张三, 李四, 王五;
        shoupiao s = new shoupiao();
        张三 = new Thread(s);
        张三.setName("z");
        李四 = new Thread(s);
        李四.setName("l");
        王五 = new Thread(s);
        王五.setName("w");
        张三.start();
        李四.start();
        王五.start();
}


}      
      

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值