Java从入门到精通 第18章 多线程

目录

实现线程的两种方式

操作线程的方法

线程的优先级

线程同步


实现线程的两种方式

每一个程序都是一个进程,一个进程可以有多个线程,线程是进程的一个执行流程

  • 继承java.lang.Thread类
  • 实现java.lang.Runnable接口 (java不支持多继承,在需要继承其他类又需要实现多线程利用接口实现)
  • 线程的生命周期:出生状态、就绪状态、运行状态、等待状态、休眠状态、阻塞状态、死亡状态

操作线程的方法

  • 线程的休眠 Thread.sleep(),sleep为Thread的静态方法,单位毫秒
  • 线程的加入 thread.join(),在线程A中加入线程B,执行完B后在执行A
  • 线程的中断 thread.interrupt(),引发InterruptedException,通常在catch中关闭数据库连接和socket连接等操作。提倡run中使用无线循环的方式,然后使用一个布尔型标记控制循环的停止。
  • 线程的礼让 yield(),对于多任务操作系统不需要使用,操作系统会自动分配CPU时间片

线程的优先级

系统始终选择就绪状态下优先级较高的线程进入运行状态。优先级高的并不一定先执行,也取决于操作系统

线程同步

多线程资源同步的问题都是采用给定时间只允许一个线程访问共享资源,给资源上一把锁

  • 同步块synchronized(),将对资源的操作放在同步块中
  • 同步方法,在方法前加synchronized修饰,某个对象调用同步方法时必须等该同步方法执行完毕后才被执行
//继承Thread
package ex18_Thread;

public class ThreadTest extends Thread {
    private int count = 10;
    public void run() {  // 覆盖run()方法
        while (true) {
            System.out.print(count + " ");
            if (--count == 0)
                return;
        }
    }

    public static void main(String args[]) {
        ThreadTest t1 = new ThreadTest();
        ThreadTest t2 = new ThreadTest();
        t1.start();  // 线程执行调用start()
        t2.start();
    }

}

 

//使用Runnable接口实现多线程
package ex18_Thread;

import javax.swing.*;
import java.awt.*;
import java.net.URL;
import java.util.EmptyStackException;

public class SwingAndThread extends JFrame {
    private JLabel jl = new JLabel();  // 声明JLable对象
    private static Thread t;  //声明线程对象
    private int count = 0;  //声明计数变量
    private Container container = getContentPane();  //声明容器

    public SwingAndThread() {
        setBounds(100,100,1000,1000);  //绝对定位窗体大小和位置
        container.setLayout(null);  //不使用任何布局管理器
        URL url = SwingAndThread.class.getResource("/ex18_Thread/1.gif");  //获取图标url
        Icon icon = new ImageIcon(url);  //实例化一个icon
        jl.setIcon(icon);  //将图标放在标签中
        jl.setHorizontalAlignment(SwingConstants.LEFT); //将图片放在左边
//        jl.setBounds(10,10,500,500);  //设置标签位置和大小
        jl.setOpaque(true);  //设置不透明

        t = new Thread(new Runnable() {  //定义匿名内部类,该类实现Runnable接口
            @Override
            public void run() {  //重写run()
                while (count <= 500) {
                    jl.setBounds(count,10,500,500);
                    try {
                        Thread.sleep(1000);  //线程休眠1000毫秒
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    count += 4;
                    if (count == 500) {  //当其回到最右边时回到最左边
                        count = 10;
                    }
                }

            }
        });
        t.start();  //启用一个新线程start(), start()运行run()方法
        container.add(jl);
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

    }
    public static void main(String args[]) {
        new SwingAndThread();
    }


}

 

//线程的休眠
package ex18_Thread;

import javax.swing.*;
import java.awt.*;
import java.util.Random;

public class SleepMethodTest extends JFrame {
    private Thread t;
    private static Color[] color = {Color.BLACK, Color.BLUE,Color.CYAN,Color.RED};
    private static final Random rand = new Random();  //创建随机对象
    private static Color getC() {
        return color[rand.nextInt(color.length)];
    }

    public SleepMethodTest() {
        t = new Thread(new Runnable() {
            int x = 100;
            int y = 100;
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //获取组件绘图上下文对象
                    Graphics graphics = getGraphics();
                    graphics.setColor(getC());  //设置绘图颜色
                    graphics.drawLine(x, y+=10, 800, y);
                    if (y >= 800) {
                        y = 100;
                    }
                }
            }
        });
        t.start();
    }

    public static void main(String args[]) {
        init(new SleepMethodTest(),1000,1000);
    }

    //设置窗体的各种属性的方法
    public static void init(JFrame frame, int width, int height) {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(width, height);
        frame.setVisible(true);
    }

}

 

//线程的加入
package ex18_Thread;

import javax.swing.*;
import java.awt.*;

public class JoinTest extends JFrame {
    private Thread threadA;
    private Thread threadB;
    final JProgressBar jProgressBar = new JProgressBar();
    final JProgressBar jProgressBar1 = new JProgressBar();
    int count = 0;
    public JoinTest() {
        super();
        getContentPane().add(jProgressBar, BorderLayout.NORTH);
        getContentPane().add(jProgressBar1, BorderLayout.SOUTH);
        jProgressBar.setStringPainted(true);
        jProgressBar1.setStringPainted(true);
        //使用匿名内部类初始化Thread实例
        threadA = new Thread(new Runnable() {
            int count = 0;
            @Override
            public void run() {
                while (true) {
                    jProgressBar.setValue(count++);
                    try {
                        Thread.sleep(100);
                        threadB.join();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        threadA.start();

        threadB = new Thread(new Runnable() {
            int count = 0;
            @Override
            public void run() {
                while (true) {
                    jProgressBar1.setValue(count++);
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    if (count + 1 == 100)
                        break;
                }
            }
        });
        threadB.start();

    }



    public static void main(String args[]) {
        init(new JoinTest(), 100,100);
    }

    //设置窗体的各种属性的方法
    public static void init(JFrame frame, int width, int height) {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(width, height);
        frame.setVisible(true);
    }
}

 

//线程的中断
package ex18_Thread;

import javax.swing.*;
import java.awt.*;

public class InterruptedSwing extends JFrame {
    Thread thread;

    public InterruptedSwing() {
        super();
        final JProgressBar progressBar = new JProgressBar();
        getContentPane().add(progressBar, BorderLayout.NORTH);
        progressBar.setStringPainted(true);
        thread = new Thread(new Runnable() {
            int count = 0;
            @Override
            public void run() {
                while (true) {
                    progressBar.setValue(count++);
                    try {
                        thread.sleep(1000);
                    } catch (InterruptedException e) {
                        System.out.println("当前程序被中断");
                        break;
                    }
                }


            }
        });
        thread.start();
        thread.interrupt();
    }

    public static void main(String[] args) {
        init(new InterruptedSwing(), 100, 100);
    }

    //设置窗体的各种属性的方法
    public static void init(JFrame frame, int width, int height) {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(width, height);
        frame.setVisible(true);
    }


}

 

 

 

你可能感兴趣的:(Java)