java——线程学习笔记

1、线程的理解:
(1)线程的使用:

线程的学习难点并不在于如何创建、开启一个线程,而是应该何时创建,线程如何同步,使得程序能够运行得到预期的结果。
比如文字处理程序 你可以设置每隔多长时间 输入的内容可以自动的保存 而这个保存操作并不需要你的介入 而是使用一个线程专门负责这个操作,在这个程序中至少得有两个线程 一个便是主线程 用来捕获你从键盘输入的内容 而另一个线程则负责定时保存输入的内容。
在后面的socket的学习中也用到了多线程:

(2)线程的执行:

只有在多处理器的机器上, 多线程才会被真正的同时运行,在单处理机上多线程是占用分配的时间片来运行,因为处理机的速度比较快 使得我们看起来它像是在同时运行,也就是我们操作系统中所说的并发和并行的概念。

2、线程的创建:
方法一:定义线程实现Runnable接口
方法二:定义一个Thread的子类并重写run方法

代码实现

public class MyThread implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<10;i++) {
            System.out.println("myThread"+i);
        }
    }
}

public class MyThread1 extends Thread {
    public void run() {
        for(int i=0;i<10;i++) {
            System.out.println("MyThread"+i);
        }
    }
}

public class MainTread {
    public static void main(String[] args) {
            Runnable r1=new MyThread();
            //r1.run();这样只是执行了线程体,而不是开辟出类一个线程与主线程同时运行

            //这样就开辟出来一个新的线程 Thread(Runnable target)
            Thread t=new Thread(r1);//要启动一个新的线程就必须new一个Thread对象出来
            t.start();//线程启动调用start方法 线程执行默认运行的run()方法  

            /*
                方法二:
                MyThread1 mt=new MyThread1();
                mt.start();
            */
            for(int i=0;i<10;i++){
                System.out.println("mainthod:"+i);
            }

    }
}
3、线程的管理
(1)join()
    等待该线程终止,在当前线程中调用另一个线程的jion方法,则当前线程转入阻塞状态,直到另一个线程运行结束后,当前线程才会由阻塞状态转为就绪状态
代码实现:
    public class MainThread {
    public static void main(String[] args) {
        MyThread mt=new MyThread();
        MyThread1 mt1=new MyThread1();
        /*
         * Thread(Runnable target)分配新的target对象
         * */
        Thread tr1=new Thread(mt1);
        Thread tr=new Thread(mt);
        tr1.start();
        tr.start();

        try {
            tr1.join();
            tr.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        for(int i=0;i<50;i++) {
            System.out.println("MainThread"+i);
        }

        //tr1与tr线程若放在后面启动的话  则是等主线程结束后才会启动执行
        /*
         * 那么此处我们就开始思考了  线程的并发执行是无序的   我们该如何使得线程能够按照某种顺序执行呢?
         * 即采用jion方法了
         * */
        //tr1.start();
        //tr.start();

    }
此处代码运行的结果是 待tr tr1线程运行结束后 主线程才会开始运行
(2)yield和sleep

yield和sleep(0)实现的效果一样,因此我们可以发现它俩的区别是sleep可以规定该线程多长时间内不可以抢占处理机,而yield()不可以,它意味着该线程放弃处理机后立马可以参加抢占处理机
代码实现:

public class MyThread implements Runnable {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<50;i++) {
            /*
             * 每循环一次 该线程让出了处理机   即处理机重新选择分配给一个线程 进行运行  仍有可能分配给原来的线程
             * */
            Thread.yield();
            System.out.println("MyThread"+i);
        }
    }

}

public class MyThread implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(1000);//该线程休眠 5秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for(int i=0;i<50;i++) {

            System.out.println("MyThread"+i);
        }
    }

}
(3)设置线程的优先级
需要注意的是Java中
 优先级高的线程只能有机会优先被执行  而不会绝对被优先执行
代码实现:
public class MainThread {
    /*
     * 线程优先级设置测试
     * */
    public static void main(String[] args) {
        MyThread1 mt1=new MyThread1();
        MyThread2 mt2=new MyThread2();

        Thread tr1=new Thread(mt1);
        Thread tr2=new Thread(mt2);
        int p1 = tr1.getPriority();
        int p2 = tr2.getPriority();

        System.out.println(p1+"   "+p2);//线程的默认优先级为5

        //设置线程的优先级
        tr1.setPriority(10);
        tr2.setPriority(7);
        tr1.start();

        tr2.start();

        for(int i=0;i<50;i++) {
            System.out.println("MainThread  "+i);
        }   
    }
}
(4)wait(),notify()与 synchronized

需要先明白以下几个问题:
1、如何使用?
(1)obj.wait()(等待) 与 obj.notify()(唤醒) 必须要与synchronized(obj)方法一起使用
(2)wait()必须在synchronized代码块中,它使得当前线程等待,直到其它线程调用此对象的notify()或notifyAll()方法,即其它线程唤醒自己。
(3)notify()方法可不可以自己唤醒自己? 答案当然是NO,notify()唤醒的是在等待队列中的线程,自己就没有在等待队列,需要注意的是notify()唤醒的是等待队列中的随机一个线程, notifyAll()可将等待队列中的所有的线程全部唤醒
2、wait()与sleep的区别 。
sleep是线程的方法 wait是object的方法 sleep释放的CPU的抢占权 wait()将CPU的抢占权跟锁全部都释放

3、为什么要使用 synchronized?
多线程操作同一个对象的时候要加锁,不加锁的话会导致程序的执行无可再现性,每次的运行结果都不相同。
说了这么一大堆,比较抽象,使用线程模拟生产者消费者问题会加深理解 。
线程模拟生产者消费者问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值