public class MyCallable implements Callable {
    @Override
    public Object call() throws Exception {
        //返回值表示多线程运行结果
        int sum=0;
        for (int i = 0; i < 100; i++) {
            sum+=i;
        }
        return sum;
    }
}
-------------------
public class MyRun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+i);//Thread.currentThread()返回的是当前线程的对象
        }
    }
}
-----------------------
public class MyThread1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+i);
        }
    }
}
-----------------------
线程的三种启动方式:


------------------------
public class ThreadDemo1 {
    public static void main(String[] args) {
        /*
        多线程第一种启动方式
        1.自己定义一个类继承Thread类
        2.重写run方法
        3.创建子类对象并启动线程
         */
        MyThread1 mt=new MyThread1();//创建对象
        MyThread1 mt2=new MyThread1();
        //起名字
        mt.setName("线程1: ");
        mt2.setName("线程2: ");

        mt.start();//启动线程
        mt2.start();
    }
}
-------------------
public class ThreadDemo2 {
    public static void main(String[] args) {
        /*
        多线程第二种启动方式
        1.自己定义一个类实现Runnable接口
        2.重写run方法
        3.创建自己类对象
        4.创建一个Thread类对象,并启动线程
         */

        //创建MyRun对象
        //表示多线程要执行的任务
        MyRun mr=new MyRun();
        //创建Thread类对象
        Thread t=new Thread(mr);
        Thread t2=new Thread(mr);
        //起名字
        t.setName("线程1: ");
        t2.setName("线程2: ");
        //启动线程
        t.start();
        t2.start();
    }
}
------------------
public class ThreadDemo3 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        /*
        多线程第二种启动方式
        特点:可以获得多线程运行的结果

        1.创建一个类MyCallable实现Callable接口
        2.重写call方法(是有返回值的,表示多线程运行结果)
        3.创建MyCallable对象
        4.创建FutureTask的对象(管理多线程运行结果)
        5.创建Thread对象,并启动线程
         */

        //1.创建MyCallable对象
        MyCallable mc=new MyCallable();
        //2.创建Future的对象(管理多线程运行结果)
        FutureTask<Integer> ft=new FutureTask<>(mc);
        //3.创建Thread对象,并启动线程
        Thread tr=new Thread(ft);
        //起名字
        tr.setName("线程1: ");
        //启动线程
        tr.start();

        //获取多线程运行结果
        System.out.println(ft.get());
    }
}
---------------------------
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+"@"+i);
        }
    }
}
---------------------
public class MyThread extends Thread {

    public MyThread(String name) {
        super(name);
    }

    public MyThread() {
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+"@"+ i);
            //设置礼让线程,出让cpu使用权
            Thread.yield();
        }
    }
}
-----------------
public class MyThread2 extends Thread{
    public MyThread2(String name) {
        super(name);
    }

    public MyThread2() {
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+"@"+ i);
        }
    }
}
--------------
public class ThreadDemo1 {
    public static void main(String[] args) throws InterruptedException {
        /*
        static Thread currentThread()//返回当前线程的对象
        //没设置线程名字也有默认名字
        //设置名字可以用set方法也可以用构造方法继承父类构造方法
        static void sleep(long millis)//让当前线程休眠millis毫秒
         */

        MyThread t1=new MyThread("n1");
        MyThread t2=new MyThread("n2");
        t1.start();//启动线程,调用run()方法
        t2.start();//启动线程,调用run()方法

        Thread tt1=Thread.currentThread();
        System.out.println(tt1.getName());

        System.out.println("111");
        Thread.sleep(3000);
        System.out.println("222");
    }
}
----------------------------
public class ThreadDemo2 {
    public static void main(String[] args) {
        /*
        setPriority(int newPriority)//设置线程优先级,范围是1-10,默认是5 ,数值越大优先级越高
        final int getPriority()//获取线程优先级
         */
        //创建myrunnable对象
        MyRunnable my1=new MyRunnable();
        //创建线程对象
        Thread t1=new Thread(my1,"n1");
        Thread t2=new Thread(my1,"n2");
        //设置线程优先级
        t1.setPriority(2);
        t2.setPriority(1);
        //获取优先级
        System.out.println(t1.getPriority());
        System.out.println(t2.getPriority());

        System.out.println(Thread.currentThread().getPriority());//main方法的默认优先级也是5
    }
}
--------------------------
public class ThreadDemo3 {
    public static void main(String[] args) {
        /*
        final void setDaemon(boolean on)//设置守护线程(备胎线程)
        细节:当其他非守护线程结束时,守护线程自动结束
         */

        Thread t1=new MyThread("n1");
        Thread t2=new MyThread2("n2");
        //设置守护线程
        t2.setDaemon(true);
        //开启
        t1.start();
        t2.start();
    }
}
-----------------------
public class ThreadDemo4 {
    public static void main(String[] args) {
        /*
    static void yield()出让线程/礼让线程 //用在run方法中
     */
        Thread t1=new MyThread("n1");
        Thread t2=new MyThread2("n2");
        //开启
        t1.start();
        t2.start();
    }
}
---------------------------
public class ThreadDemo5 {
    public static void main(String[] args) throws InterruptedException {
        /*
         final void join()插入线程
         */
        Thread t=new MyThread("nn1");
        t.start();
        //设置插入线程
       t.join();//原本是main线程和t线程并发执行,现在是t线程先执行完后,main线程再执行

        for (int i = 0; i < 10; i++) {
            System.out.println("main线程"+i);
        }
    }
}
--------------------------------
-----------
public class MyThread extends Thread{
    // 将 ticket 变量设置为静态变量,让所有线程共享
    private static int ticket = 0;
    // 定义一个静态对象作为锁,用于线程同步
    //锁必须是唯一的,所以要定义静态对象
    private static final Object lock = new Object();
    @Override
    public void run(){
        while(true){
            try {
                sleep(10);//休眠会出现线程抢夺产生错误,因此要上锁
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 使用 synchronized 块保证线程安全
            synchronized (lock) {
                if(ticket < 100){
                    ticket++;
                    System.out.println(getName()+"正在卖第"+ticket+"张票");
                }else{
                    break;
                }
            }
        }
    }
}
----------
---------------------------------
public class Test1 {
    public static void main(String[] args) {
        /*
        电影院卖票,共100张票,三个窗口同时卖票,使用多线程模拟
         */
        //创建对象
        MyThread m1=new MyThread();
        MyThread m2=new MyThread();
        MyThread m3=new MyThread();

        m1.start();
        m2.start();
        m3.start();

    }
}
--------------------------
---------
public class MyRunnable implements Runnable {
    int ticket = 0;//这里不需要用static修饰,因为runnable对象只创建一次

    @Override
    public void run() {
        while (true) {
            if (extracted()) break;
        }
    }

    private synchronized boolean extracted() {//同步方法
        if (ticket == 100) {
            return true;
        } else {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ticket++;
            System.out.println(Thread.currentThread().getName() + "正在卖第" + ticket + "张票");
        }
        return false;
    }
}
----------
--------------------
public class Test2 {
    public static void main(String[] args) {
        Runnable r=new MyRunnable();
        Thread t1=new Thread(r);
        Thread t2=new Thread(r);
        Thread t3=new Thread(r);

        t1.start();
        t2.start();
        t3.start();
    }
}
--------------------------------------
锁的用法:
------------------------------
public class MyThread1 extends Thread{
    //锁
    private static int ticket = 0;

    static Lock lock=new ReentrantLock();//定义锁
    @Override
    public void run(){
        while(true){
            lock.lock();//加锁
            try {
                if(ticket < 100){
                    sleep(10);//休眠会出现线程抢夺产生错误,因此要上锁
                    ticket++;
                    System.out.println(getName()+"正在卖第"+ticket+"张票");
                }else  {
                    break;
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }finally {
                lock.unlock();//释放锁
            }

        }
    }
}