黑马程序员_线程

“----------ASP.Net+Android+IOS开发、Net培训、期待与您交流!----------”

/*
     为什么要用多线程
     1.让计算机“同时”做多件事情,节约时间
     2.后台运行程序,提高程序的运行效率,也不会使主界面出现无法响应的情况
     3.多线程可以让一个程序“同时”处理多个事情
     4.计算机CPU大部分时间处于空闲状态,浪费了CPU的资源
     进程与线程
     1.一个进程至少有一个线程
     2.同一个进程中的多个线程可以“并发”执行
     3.线程是程序中的一个执行流,每个线程都有自己专有的寄存器(栈指针,程序计数器等),但代码区是共享的,即不同的线程可以执行相同的函数.
     4.多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务(代码),也就是说允许单个程序创建多个并行执行的线程来完成各自的任务
     如何实现多线程
     1.线程肯定是要执行一段代码的,所以要产生一个线程,必须先为该线程写一个方法,这个方法中的代码就是该线程运行所要执行的代码。(这个人来做一件事情)
     2.线程启动时,通过委托调用该方法(调用传过来的委托,委托就会执行相应的方法,实现线程执行方法).    
     产生一个线程的步骤:
     1.编写产生线程所要执行的方法
     2.实例化Thread类,并传入一个指向线程所要运行方法的委托(这时候线程已经产生,但是还没有运行)
     3.调用Thread实例的Start方法,标记该线程可以被CPU执行了,但具体执行时间由CPU决定
    
     前台线程和后台线程
     1.前台线程:只有所有的前台线程都关闭才能完成程序关闭(默认)。
     2.后台线程:只要所有的前台线程结束,后台线程自动结束(设置属性IsBackground=ture)
    
     */

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TextBox.CheckForIllegalCrossThreadCalls = false;//线程的方法中不能给UI线程中的TextBox赋值的,只有加上这句话才可以的
        }
        private void CountTime() {
            for (int i = 0; i < 999999999; i++)
            {

            }
            MessageBox.Show("循环完毕~");
        }
        private void ChangeTxt() {
            for (int i = 0; i < 1000;i++ ) {
                int a = int.Parse(txtNum.Text);
                Console.WriteLine(Thread.CurrentThread.Name+",a="+a+",i="+i);
                a++;
                this.txtNum.Text = a.ToString();//不是UI线程中的方法,不能给TextBox赋值,需加上TextBox.CheckForIllegalCrossThreadCalls = false;
            }
        
        }
        private void ShowName(object name) {
            MessageBox.Show("name="+name);
        }
        private void ShowName2(object li)
        {
            List<string> list = li as List<string>;
            foreach(string name in list){
                MessageBox.Show("name=" + name);
            }
        }
        //单线程的缺点(单击按钮后无法再拖动窗体,只有等循环完毕后才能拖动窗体)
        private void btnSingelThread_Click(object sender, EventArgs e)
        {
            CountTime();
            //ChangeTxt(); //UI线程自己访问可以给txtNum控件赋值
        }
        //使用线程来解决单线程的缺点(UI卡死问题)
        private void btnMutiThread_Click(object sender, EventArgs e)
        {
            //声明一个委托(无参无返回值)
            ThreadStart ts = new ThreadStart(CountTime);
            Thread threadFirst = new Thread(ts); //上面两行等同于Thread threadFirst = new Thread(CountTime);
            //前台线程:没有对该对象设置IsBackgroud属性
            //后台线程,当所有前台线程结束后,后台线程会自动退出(单击关闭按钮,如果不加这句话,关闭窗体后过一会还会弹出对话框)
            //threadFirst.IsBackground = true;
            threadFirst.Start();

        }
        //多线程方法重入问题(txtNum.Text!=2000)
        private void btnProblem_Click(object sender, EventArgs e)
        {
            //.net中的线程是系统线程???
            Thread thread1 = new Thread(ChangeTxt);
            thread1.Name = "t1";
            thread1.IsBackground = true;
            thread1.Start();

            Thread thread2 = new Thread(ChangeTxt);
            thread2.Name = "t2";
            thread2.IsBackground = true;
            thread2.Start();
        }
        //线程执行带参数的方法(方法的参数需是object)    
        private void btnThreadWithPara_Click(object sender, EventArgs e)
        {
            ParameterizedThreadStart pts = new ParameterizedThreadStart(ShowName);//方法的参数需是Object
            Thread thread = new Thread(pts);
            thread.IsBackground = true;//后台线程
            thread.Start(txtName.Text); //传递参数
        }
        //线程执行带多个参数的方法
        private void btnThreadWithManyPram_Click(object sender, EventArgs e)
        {
            ParameterizedThreadStart pts = new ParameterizedThreadStart(ShowName2);
            Thread thread = new Thread(pts);
            thread.IsBackground = true;//后台线程
            thread.Start(new List<string>() {"刘德华","黎明","张学友","郭富城" }); //传递参数

        }
    }


 

### 黑马程序员多线程学习笔记与资料 在Java中,多线程是实现并发编程的重要工具。以下是一些关于黑马程序员多线程学习笔记和相关资料的内容总结[^1]。 #### 线程池的工作机制 线程池是一种用于管理和复用线程的机制,能够有效减少线程创建和销毁的开销,提高系统性能。当通过`submit`方法向线程池提交任务时,其工作流程如下: - 客户端每次提交一个任务,线程池会在核心线程池中创建一个工作线程来执行这个任务。 - 如果核心线程池中的线程已满,则尝试将任务存储到工作队列中。 - 如果工作队列也满了,线程池会再次在非核心线程池区域创建新线程来执行任务,直到当前线程池总线程数量达到最大值。 - 当线程池中的线程数量超过最大值时,多余的任务将按照指定的拒绝策略进行处理。 #### 创建线程的方式 在Java中,可以通过以下几种方式创建线程: 1. **继承Thread类**:通过重写`Thread`类的`run`方法实现线程逻辑,并调用`start`方法启动线程。 2. **实现Runnable接口**:定义一个实现了`Runnable`接口的类,并在`run`方法中编写线程逻辑,然后将其传递给`Thread`类的构造函数。 3. **使用Callable和FutureTask**:`Callable`接口类似于`Runnable`,但可以返回结果并抛出异常。结合`FutureTask`可以实现更复杂的线程功能。 4. **使用线程池**:通过`ExecutorService`接口提供的线程池管理功能,简化线程的创建和管理过程。 以下是使用线程池的一个简单示例: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExample { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(5); // 创建一个固定大小的线程池 for (int i = 0; i < 10; i++) { Runnable task = () -> { System.out.println("Task executed by: " + Thread.currentThread().getName()); }; executorService.submit(task); // 提交任务到线程池 } executorService.shutdown(); // 关闭线程池 } } ``` #### 多线程同步与锁 在多线程环境中,多个线程可能同时访问共享资源,导致数据不一致的问题。为了解决这个问题,可以使用同步机制: - **synchronized关键字**:用于修饰方法或代码块,确保同一时间只有一个线程可以访问该方法或代码块。 - **Lock接口**:提供了比`synchronized`更灵活的锁机制,例如可重入锁、读写锁等。 #### 常见问题与解决方案 在多线程编程中,可能会遇到死锁、线程安全等问题。解决这些问题的关键在于合理设计线程间的协作机制,避免竞争条件的发生。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值