使用Thread创建两个线程,分别输出1~100。
实现此案例需要按照如下步骤进行。
步骤一:新建TestThread类及MyThread类
首先,新建类TestThread;然后,在该类所在的文件中新建类MyThread,MyThread类继承自Thread类,代码如下所示:
/** * 测试线程 */ public class TestThread { /** * 测试多线程并发运行 */ public static void main(String[] args) { } } /** * 线程 */ class MyThread extends Thread{ }
步骤二:实现输出1到100
在MyThead类中覆盖run方法,在该方法中实现输出1到100,代码如下所示:
/** * 测试线程 */ public class TestThread { /** * 测试多线程并发运行 */ public static void main(String[] args) { } } /** * 线程 */ class MyThread extends Thread{ #cold_bold public void run(){ #cold_bold for(int i=1;i<=100;i++){ #cold_bold System.out.println(i); #cold_bold } #cold_bold } }
步骤三:创建并启动线程
在TestThread类的main方法中,创建两个线程t1和t2,然后使用线程t1、t2的start方法启动线程,代码如下所示:
/** * 测试线程 */ public class TestThread { /** * 测试多线程并发运行 */ #cold_bold public static void main(String[] args) { #cold_bold Thread t1 = new MyThread(); #cold_bold Thread t2 = new MyThread(); #cold_bold t1.start(); #cold_bold t2.start(); #cold_bold } } /** * 线程 */ class MyThread extends Thread{ public void run(){ for(int i=1;i<=100;i++){ System.out.println(i); } } }
运行TestThread类,控制台会输出两次1到100。
本案例的完整代码如下所示:
/** * 测试线程 */ public class TestThread { /** * 测试多线程并发运行 */ public static void main(String[] args) { Thread t1 = new MyThread(); Thread t2 = new MyThread(); t1.start(); t2.start(); } } /** * 线程 */ class MyThread extends Thread{ public void run(){ for(int i=1;i<=100;i++){ System.out.println(i); } } }
编写一个线程改变窗体的颜色,详细要求如下:
1)使用Runnable创建线程,该线程实现窗口的颜色在黑色和白色之间不断的切换。
2)使用内部类创建线程的方式,实现窗口的颜色在黑色和白色之间不断的切换。
实现此案例需要按照如下步骤进行。
步骤一:新建类TestRunnable
创建TestRunnable类,该类继承自JFrame类,并实现Runnable接口,代码如下所示:
import javax.swing.JFrame; /** * 测试Runnable */ public class TestRunnable extends JFrame implements Runnable{ public static void main(String[] args) { } }
步骤二:覆盖Runnable接口的run方法,实现窗体颜色切换
在TestRunnable类中,覆盖Runnable接口的run方法。在该方法中,首先创建JPanel类的对象panel,并将其放在窗体上;然后,使用while(true)循环,在循环中,切换panel的颜色从而达到窗体颜色变化,代码如下所示:
import java.awt.Color; import javax.swing.JFrame; import javax.swing.JPanel; /** * 测试Runnable */ public class TestRunnable extends JFrame implements Runnable{ #cold_bold @Override #cold_bold public void run() { #cold_bold int i = 0; #cold_bold JPanel panel = new JPanel(); #cold_bold panel.setSize(300, 300); #cold_bold this.setContentPane(panel); #cold_bold while(true){ #cold_bold i = i==0?1:0; #cold_bold if(i==0){ #cold_bold panel.setBackground(Color.BLACK); #cold_bold }else{ #cold_bold panel.setBackground(Color.WHITE); #cold_bold } #cold_bold } } public static void main(String[] args) { } }
步骤三:显示窗体、启动线程
在TestRunnable类的main方法中,首先设置窗体显示,然后启动线程,代码如下所示:
import java.awt.Color; import javax.swing.JFrame; import javax.swing.JPanel; /** * 测试Runnable */ public class TestRunnable extends JFrame implements Runnable{ @Override public void run() { int i = 0; JPanel panel = new JPanel(); panel.setSize(300, 300); this.setContentPane(panel); while(true){ i = i==0?1:0; if(i==0){ panel.setBackground(Color.BLACK); }else{ panel.setBackground(Color.WHITE); } } } public static void main(String[] args) { #cold_bold TestRunnable r = new TestRunnable(); #cold_bold r.setSize(300, 300); #cold_bold r.setVisible(true); #cold_bold r.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); #cold_bold Thread t = new Thread(r); #cold_bold t.start(); } }
运行TestRunnable类会显示窗体,窗体在黑色和白色之间不断切换。
步骤四:使用内部类的方式创建线程
使用内部类创建线程的方式,实现窗口的颜色在黑色和白色之间不断的切换,代码如下所示:
import java.awt.Color; import javax.swing.JFrame; import javax.swing.JPanel; /** * 使用匿名内部类形式创建线程 * @author Xiloer * */ public class TestInnerThread { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(300,300); final JPanel panel = new JPanel(); panel.setSize(300,300); frame.setContentPane(panel); frame.setVisible(true); Thread t = new Thread(){ public void run(){ int i =0; while(true){ i = i==0?1:0; if(i==0){ panel.setBackground(Color.BLACK); }else{ panel.setBackground(Color.WHITE); } } } }; t.start(); } }
本案例中,类TestRunnable的完整代码如下所示:
import java.awt.Color; import javax.swing.JFrame; import javax.swing.JPanel; /** * 测试Runnable */ public class TestRunnable extends JFrame implements Runnable{ @Override public void run() { int i = 0; JPanel panel = new JPanel(); panel.setSize(300, 300); this.setContentPane(panel); while(true){ i = i==0?1:0; if(i==0){ panel.setBackground(Color.BLACK); }else{ panel.setBackground(Color.WHITE); } } } public static void main(String[] args) { TestRunnable r = new TestRunnable(); r.setSize(300, 300); r.setVisible(true); r.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Thread t = new Thread(r); t.start(); } }
类TestInnerThread的完整代码如下所示:
import java.awt.Color; import javax.swing.JFrame; import javax.swing.JPanel; /** * 使用匿名内部类形式创建线程 * @author Xiloer * */ public class TestInnerThread { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(300,300); final JPanel panel = new JPanel(); panel.setSize(300,300); frame.setContentPane(panel); frame.setVisible(true); Thread t = new Thread(){ public void run(){ int i =0; while(true){ i = i==0?1:0; if(i==0){ panel.setBackground(Color.BLACK); }else{ panel.setBackground(Color.WHITE); } } } }; t.start(); } }
测试currentThread方法,详细要求如下:
1)新建类TestCurrentThread,在该类中创建方法testCurrent实现输出当前线程。
2)在TestCurrentThread类的main方法中,输出当前线程并调用testCurrent查看当前线程。
3)在main方法中,使用内部类创建线程t,该线程中实现输出当前线程并调用testCurrent查看当前线程。
4)启动线程t。
实现此案例需要按照如下步骤进行。
步骤一:新建TestCurrentThread类,添加testCurrent方法
新建类TestCurrentThread,在该类中创建方法testCurrent,在该方法中使用Thread类的静态方法currentThread获取当前线程并输出当前线程,代码如下所示:
/** * 测试当前线程 */ public class TestCurrentThread { public static void main(String[] args) { } /** * 测试不同线程调用该方法时,获取这个线程 */ public static void testCurrent(){ System.out.println("运行testCurrent方法的线程是:"+Thread.currentThread()); } }
步骤二:在main方法中获取当前线程
在TestCurrentThread类的main方法中,输出当前线程并调用testCurrent查看当前线程,代码如下所示:
/** * 测试当前线程 */ public class TestCurrentThread { public static void main(String[] args) { #cold_bold System.out.println("运行main方法的线程:"+Thread.currentThread()); #cold_bold testCurrent(); } /** * 测试不同线程调用该方法时,获取这个线程 */ public static void testCurrent(){ System.out.println("运行testCurrent方法的线程是:"+Thread.currentThread()); } }
运行TestCurrentThread方法,控制台输出结果如下:
运行main方法的线程:Thread[main,5,main] 运行testCurrent方法的线程是:Thread[main,5,main]
输出结果中的“Thread[main,5,main]”表示当前线程的名字为main、优先级为5、当前线程的组线程为main。
步骤三:在内部类中查看当前线程
在main方法中,首先,使用内部类创建线程t,该线程中实现输出当前线程并调用testCurrent查看当前线程;然后启动线程t,代码如下所示:
/** * 测试当前线程 */ public class TestCurrentThread { public static void main(String[] args) { System.out.println("运行main方法的线程:"+Thread.currentThread()); testCurrent(); #cold_bold Thread t = new Thread(){ #cold_bold @Override #cold_bold public void run() { #cold_bold System.out.println("线程t:"+Thread.currentThread()); #cold_bold testCurrent(); #cold_bold } #cold_bold }; #cold_bold t.start(); } /** * 测试不同线程调用该方法时,获取这个线程 */ public static void testCurrent(){ System.out.println("运行testCurrent方法的线程是:"+Thread.currentThread()); } }
运行TestCurrentThread类,控制台的输出结果如下:
运行main方法的线程:Thread[main,5,main] 运行testCurrent方法的线程是:Thread[main,5,main] #cold_bold线程t:Thread[Thread-0,5,main] #cold_bold运行testCurrent方法的线程是:Thread[Thread-0,5,main]
输出结果中的“Thread[Thread-0,5,main]”表示当前线程的名字为Thread-0、优先级为5、当前线程的组线程为main。
本案例的完整代码如下所示:
/** * 测试当前线程 */ public class TestCurrentThread { public static void main(String[] args) { System.out.println("运行main方法的线程:"+Thread.currentThread()); testCurrent(); Thread t = new Thread(){ @Override public void run() { System.out.println("线程t:"+Thread.currentThread()); testCurrent(); } }; t.start(); } /** * 测试不同线程调用该方法时,获取这个线程 */ public static void testCurrent(){ System.out.println("运行testCurrent方法的线程是:" +Thread.currentThread()); } }
测试Thread类的getName方法和getID方法,详细要求如下:
1)创建两个线程,输出默认的线程名字和默认的ID。
2)创建一个线程,设置线程的名字并输出线程名字和默认的ID。
实现此案例需要按照如下步骤进行。
步骤一:获取默认的线程名字和ID
首先,新建类TestThreadNameAndId,在该类的main方法中,创建两个线程t0、t1;接着分别使用Thread类的getName方法和getId方法获取线程的名字和ID,代码如下所示:
/** * 获取线程名字及ID */ public class TestThreadNameAndId { /** * 测试线程的getName方法以及getId方法 */ public static void main(String[] args) { Thread t = new Thread(); System.out.println(t.getName()); System.out.println(t.getId()); Thread t1 = new Thread(); System.out.println(t1.getName()); System.out.println(t1.getId()); } }
运行TestThreadNameAndId类,控制台的输出结果如下:
Thread-0 9 Thread-1 10
从输出结果可以看出,默认的线程名字为“Thread-+数字”的形式;ID为从数字9开始的,这是因为,9之前的数字被虚拟机的线程占用掉了。
步骤二:为线程添加自定义的名字
在构造Thread类的对象时,可以通过Thread(String)这个构造方法给线程自定义名字,代码如下所示:
/** * 获取线程名字及ID */ public class TestThreadNameAndId { /** * 测试线程的getName方法以及getId方法 */ public static void main(String[] args) { Thread t = new Thread(); System.out.println(t.getName()); System.out.println(t.getId()); Thread t1 = new Thread(); System.out.println(t1.getName()); System.out.println(t1.getId()); #cold_bold Thread t2 = new Thread("自定义名字的Thread"); #cold_bold System.out.println(t2.getName()); #cold_bold System.out.println(t2.getId()); } }
运行TestThreadNameAndId类,控制台的输出结果如下:
Thread-0 9 Thread-1 10 #cold_bold自定义名字的Thread #cold_bold11
从输出结果可以看出,当通过构造方法设置自定义名字后,使用Thread类的getName方法获取名字时得到的则是自定义的名字。
本案例的完整代码如下所示:
/** * 获取线程名字及ID */ public class TestThreadNameAndId { /** * 测试线程的getName方法以及getId方法 */ public static void main(String[] args) { Thread t = new Thread(); System.out.println(t.getName()); System.out.println(t.getId()); Thread t1 = new Thread(); System.out.println(t1.getName()); System.out.println(t1.getId()); Thread t2 = new Thread("自定义名字的Thread"); System.out.println(t2.getName()); System.out.println(t2.getId()); } }
测试守护线程,详细要求如下:
1)使用内部类创建线程的方式创建线程d,该线程实现每隔0.1秒输出字符串“后台线程”。
2)设置线程d为守护线程并启动该线程。
3)使main线程阻塞5秒,然后输出字符串"main线程结束了"。
实现此案例需要按照如下步骤进行。
步骤一:创建线程,实现每隔0.1秒输出字符串“后台线程”
首先新建类TestDaemonThread;然后在该类的main方法中,使用内部类创建线程的方式创建线程d;最后,线程d实现每隔0.1秒输出字符串“后台线程”,代码如下所示:
public class TestDaemonThread { public static void main(String[] args) { Thread d = new Thread(){ public void run() { while(true){ System.out.println("后台线程"); try { Thread.sleep(100); } catch (InterruptedException e) { } } } }; } }
步骤二:设置d线程为后台线程
在main方法中,首先,设置d线程为后台线程并启动该线程;然后,使用Thread类的sleep方法使main线程阻塞5秒;最后,输出字符串“main线程结束了”,代码如下所示:
public class TestDaemonThread { public static void main(String[] args) { Thread d = new Thread(){ public void run() { while(true){ System.out.println("后台线程"); try { Thread.sleep(100); } catch (InterruptedException e) { } } } }; #cold_bold d.setDaemon(true); #cold_bold d.start(); #cold_bold try { #cold_bold Thread.sleep(5000); #cold_bold } catch (InterruptedException e) { #cold_bold } #cold_bold //进程中所有前台线程结束后,后台线程强制结束 #cold_bold System.out.println("main线程结束了"); } }
运行TestDaemonThread类,控制台会不断输出字符串“后台线程”,直到输出字符串“main线程结束了”为止。这是因为,d线程被设置为守护线程,守护线程的特点是,当进程中只剩下守护线程时,所有守护线程强制终止。
本案例的完整代码如下所示:
public class TestDaemonThread { public static void main(String[] args) { Thread d = new Thread(){ public void run() { while(true){ System.out.println("后台线程"); try { Thread.sleep(100); } catch (InterruptedException e) { } } } }; d.setDaemon(true); d.start(); try { Thread.sleep(5000); } catch (InterruptedException e) { } //进程中所有前台线程结束后,后台线程强制结束 System.out.println("main线程结束了"); } }
在案例“编写一个线程改变窗体的颜色V1”基础上实现当前案例,即,在使用内部类创建线程的方式,实现窗口的颜色在黑色和白色之间不断的切换的基础上,实现每隔一秒窗体的颜色在黑色和白色之间切换。
实现此案例需要按照如下步骤进行。
步骤一:新建TestSleep类
新建TestSleep类,使该类中的代码与TestInnerThread类中的代码保持一致,代码如下所示:
/** * 测试sleep方法 */ public class TestSleep { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(300,300); final JPanel panel = new JPanel(); panel.setSize(300,300); frame.setContentPane(panel); frame.setVisible(true); Thread t = new Thread(){ public void run(){ int i =0; while(true){ i = i==0?1:0; if(i==0){ panel.setBackground(Color.BLACK); }else{ panel.setBackground(Color.WHITE); } } } }; t.start(); } }
步骤二:实现颜色切换
使用Thread类的sleep方法实现每隔一秒窗体的颜色在黑色和白色之间切换,代码如下所示:
/** * 测试sleep方法 */ public class TestSleep { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(300,300); final JPanel panel = new JPanel(); panel.setSize(300,300); frame.setContentPane(panel); frame.setVisible(true); Thread t = new Thread(){ public void run(){ int i =0; while(true){ i = i==0?1:0; if(i==0){ panel.setBackground(Color.BLACK); }else{ panel.setBackground(Color.WHITE); } #cold_bold try { #cold_bold Thread.sleep(1000); #cold_bold } catch (InterruptedException e) { #cold_bold e.printStackTrace(); #cold_bold } } } }; t.start(); } }
运行TestSleep类,会显示窗体,窗体上的颜色每隔一秒在黑色和白色之间切换。
本案例中,类TestSleep的完整代码如下所示:
/** * 测试sleep方法 */ public class TestSleep { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(300,300); final JPanel panel = new JPanel(); panel.setSize(300,300); frame.setContentPane(panel); frame.setVisible(true); Thread t = new Thread(){ public void run(){ int i =0; while(true){ i = i==0?1:0; if(i==0){ panel.setBackground(Color.BLACK); }else{ panel.setBackground(Color.WHITE); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }; t.start(); } }
使用两个线程模拟图片下载的过程,详细要求如下:
1) 创建线程t1,该线程模拟实现图片下载的过程,即在该线程中实现输出字符串“t1:正在下载图片:”+下载的百分数,例如:“t1:正在下载图片:30%”;到100%之后,显示“t1:图片下载完成”。
2)创建线程t2,在该线程中,首先输出“t2:等待图片下载完毕”;然后将t1线程作为t2线程的子线程;最后,输出"t2:显示图片"。
3)启动线程t1,t2。
4)要求,一定是线程t1执行完毕之后,才会执行线程 t2 中的显示图片。即显示了“t1:图片下载完成”之后,才会显示“t2:显示图片”。
实现此案例需要按照如下步骤进行。
步骤一:创建线程t1
新建类TestJoin,该类的main方法中创建线程t1,该线程模拟实现图片下载的过程,即在该线程中实现输出字符串“t1:正在下载图片:”+下载的百分数,例如:“t1:已下载图片:30%”,代码如下所示:
public class TestJoin { public static void main(String[] args) { final Thread t1 = new Thread(){ public void run(){ for(int i=0;i<=10;i++){ System.out.println("t1:正在下载图片:"+i*10+"%"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("t1:图片下载完成"); } }; } }
步骤二:创建线程t2
在main方法中,创建线程t2,在该线程中,首先输出“t2:等待图片下载完毕”;然后将t1线程作为t2线程的子线程;最后,输出"t2:显示图片",代码如下所示:
public class TestJoin { public static void main(String[] args) { final Thread t1 = new Thread(){ public void run(){ for(int i=0;i<=10;i++){ System.out.println("t1:正在下载图片:"+i*10+"%"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("t1:图片下载完成"); } }; #cold_bold Thread t2 = new Thread(){ #cold_bold public void run(){ #cold_bold System.out.println("t2:等待图片下载完毕"); #cold_bold try { #cold_bold t1.join(); #cold_bold } catch (InterruptedException e) { #cold_bold e.printStackTrace(); #cold_bold } #cold_bold System.out.println("t2:显示图片"); #cold_bold } #cold_bold }; } }
步骤三:启动线程
启动线程t1,t2,代码如下所示:
public class TestJoin { public static void main(String[] args) { final Thread t1 = new Thread(){ public void run(){ for(int i=0;i<=10;i++){ System.out.println("t1:正在下载图片:"+i*10+"%"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("t1:图片下载完成"); } }; Thread t2 = new Thread(){ public void run(){ System.out.println("t2:等待图片下载完毕"); try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2:显示图片"); } }; #cold_bold t1.start(); #cold_bold t2.start(); } }
步骤四:测试
运行TestJoin类,控制台会输出“t2:等待图片下载完毕”,也会输出“t1:正在下载图片:0%”,以及“t1:正在下载图片:10%“等信息。最后,直到输出“t1:图片下载完成”后,才会输出“t2:显示图片”。
这是因为使用了join方法,该方法在此用于等待t1线程执行结束,再执行t2线程。
本案例中,类TestJoin的完整代码如下所示:
public class TestJoin { public static void main(String[] args) { final Thread t1 = new Thread(){ public void run(){ for(int i=0;i<=10;i++){ System.out.println("t1:正在下载图片:"+i*10+"%"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("t1:图片下载完成"); } }; Thread t2 = new Thread(){ public void run(){ System.out.println("t2:等待图片下载完毕"); try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2:显示图片"); } }; t1.start(); t2.start(); } }