多线程学习历程

1、多线程的两种实现方式

    public static void main(String[] args) {
        // 创建一个线程对象
        Thread thread = new Thread(
        // 构造方法内的创建一个线程对象
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("实现线程构造方法实现线程");
                    }
                })
        // 创建一个线程实例
        {
            @Override
            public void run() {
                System.out.println("子类实现线程");
            }
        };
        thread.start();
    }

2、多线程的应用,定时器

        
        /**
         * 第二个参数的意思是,当你调用该方法后,该方法必然会调用 TimerTask 类 TimerTask 类 中的 run()方法,
         * 这个参数就是这两者之间的差值,转换成汉语的意思就是说,用户调用 schedule() 方法后,要等待这么长的时间才可以第一次执行run() 方法。
         * 第三个参数的意思就是,第一次调用之后,从第二次开始每隔多长的时间调用一次 run() 方法。
         */
        Timer t = new Timer();
        t.schedule(new TimerTask(){

            @Override
            public void run() {
                System.out.println("10");
            }
            
        }, 1000,1000);

3、线程的同步通信与互斥

条件:共享一个对象

package com.czz.threadtest;

/**
 * 实现线程同步的信息
 * 
 * @author 刘新洲
 *
 */
public class Traditionsynchronized {

    public static void main(String[] args) {
        Traditionsynchronized ts = new Traditionsynchronized();
        ts.init();
    }

    public void init() {
        // 第一个线程调用创建一个对象
        final OutPuer out = new OutPuer();
        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                while (true) {
                    out.outPirnt("zhangsan");
                }
            }
        }.start();
        // 第二个线程调用一个对象
        final OutPuer out1 = new OutPuer();

        new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                while (true) {

                    // 当与第一个线程使用同一个对象时可以实现线程同步synchronized (this){
                    // out.outPirnt("lisi");
                    // 当与第一个线程使用不同的对象时,就不可以实现线程同步synchronized (this){
                    // out1.outPirnt("2453453");
                    // 如果一个方法类方法,那么对类方法实现同步,需要实现对该类的二进制对象进行同步
                    out.outPirntstatic("2453453");
                    out1.outPirntnotsyn("!@!¥!#!");
                }
            }
        }.start();
    }

    /**
     * 实名内部类 无论是同步方法,还是同步对象,都是对同一个对象的共享资源进行同步
     * 
     * @author 刘新洲
     *
     */
    static class OutPuer {
        public static synchronized void outPirntstatic(String name) {

            int len = name.length();
            // 如果将name锁定,那么在调用的时候name
            // 是new的不用的对象,那么现在这用方式,就是锁住了不同的对象,那么必然起不到同步的作用
            // synchronized(name){
            // 若果现在锁住的是this的话,因为在调用的时候是用的同一个对象,那么现在this的调用者就是同一个对象,所以就为同一个对象加了锁
            // synchronized(this){
            for (int i = 0; i < len; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println();
            // }
        }

        public void outPirnt(String name) {

            int len = name.length();
            // 如果将name锁定,那么在调用的时候name
            // 是new的不用的对象,那么现在这用方式,就是锁住了不同的对象,那么必然起不到同步的作用
            // synchronized(name){
            // 若果现在锁住的是this的话,因为在调用的时候是用的同一个对象,那么现在this的调用者就是同一个对象,所以就为同一个对象加了锁
            // synchronized(this){
            // 如果想实现与类方法的同步outPirntstatic必须实现二进制码的同步
            synchronized (OutPuer.class) {
                for (int i = 0; i < len; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println();
            }
        }

        /**
         * 然而,当一个线程访问object的一个synchronized(this)同步代码块时,
         * 另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
         * 
         * @param name
         */
        public void outPirntnotsyn(String name) {

            int len = name.length();
            for (int i = 0; i < len; i++) {
                System.out.print("not sysn " + name.charAt(i));
            }
            System.out.println();

        }

    }
}

4、线程面试题目

package com.czz.threadtest;

/**
 * 需求: 子线程循环10,主线程循环20,接着子线程循环10次,主线程循环20次,如此循环3次
 * 
 * @author 001
 *
 */
public class ThreadForTest {
    
    public static void main(String[] args) {
        final Bussiness buss = new Bussiness();
        new Thread(){
            public void run() {
                for (int i = 1; i <= 3; i++) {
                    buss.sub(i);
                }
                
            };
        }.start();
        
        for (int i = 1; i <= 3; i++) {
            buss.main(i);
        }
    }


}
class Bussiness{
    private boolean isSubFlag = true;
    

    public synchronized void sub(int j){
        
        while(!isSubFlag){
            
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        this.notify();
        for (int i = 1; i <= 10; i++) {
            System.out.println("第"+j+"次执行,子线程输出"+i);
        }
        isSubFlag= false;
    }
    public synchronized void main(int j){
        
        while(isSubFlag){
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        this.notify();
        
        for (int i = 1; i <= 20; i++) {
            System.out.println("第"+j+"次执行,主线程输出"+i);
        }
        isSubFlag= true;
    }
}


你可能感兴趣的:(多线程学习历程)