进程:
线程:
进程与线程区别:
线程使用场合:
实现多线程有几种方法?
三种,
1.继承Thread类,重写run函数
2.实现Runnable接口,重写run函数
3.实现Callable接口,重写call函数
thread:
public class testThread {
/**
* 测试多线程并发
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
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);
}
}
}
runnable:
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class testRunnable extends JFrame implements Runnable{
/**
* 测试runnable
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
testRunnable r = new testRunnable();
r.setSize(300,300);
r.setVisible(true);
r.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Thread t = new Thread(r);
t.start();
}
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.YELLOW);
}
}
}
}
使用匿名内部类创建线程:
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class testInnerThread {
/**
* 使用匿名内部类方式创建线程
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
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();
}
}
一道面试题:
Sleep()和wait()有什么区别?
sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
wait().会释放锁
currentThread:
public class testCurrentThread {
/**
* 测试currentThread方法
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("运行main方法的线程是" + Thread.currentThread());
testCurrent();
Thread t = new Thread(){
public void run(){
System.out.println("线程t" + Thread.currentThread());
testCurrent();
}
};
t.start();
}
/**
* 测试不同线程调用该方法时,获取这个线程
*/
public static void testCurrent(){
System.out.println("运行testcurrent方法的线程是" + Thread.currentThread());
}
}
获取线程名字及id:
/**
* 获取线程名字及id
*/
public class testThreadNameAndId {
/**
* 测试getName及getId
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
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("黄色潜水艇");
System.out.println(t2.getName());
System.out.println(t2.getId());
}
}
守护线程:
public class testDaemonThread {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread d = new Thread(){
public void run(){
while(true){
System.out.println("后台线程");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
d.setDaemon(true);
d.start();
try {
//使main线程阻塞五秒
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//进程中所有前台线程结束后,后台线程制结束
System.out.println("main线程结束了");
}
}
线程等待join():
public class testJoin {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("t1:图片下载完毕");
}
};
Thread t2 = new Thread(){
public void run(){
System.out.println("等待t1");
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("t2显示图片");
}
};
t1.start();
t2.start();
}
}
synchronized: 锁机制:
两个线程互斥,synchronized(String string),则string相同。
线程安全与非线程安全:
线程池:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 测试线程池
* @author wangyu
*
*/
public class testExecutorService {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//线程池每次启动两个线程来执行任务,由于要求执行五次任务,所以
//线程池要求分三次执行。
ExecutorService threadPool = Executors.newFixedThreadPool(2);
for(int i = 0; i < 5; i++){
Handler handler = new Handler();
threadPool.execute(handler);
}
}
}
class Handler implements Runnable{
public void run(){
String name = Thread.currentThread().getName();
System.out.println("正在执行的线程" + name);
for(int i = 0; i < 10; i++){
System.out.println(name + ":" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(name + "任务完成");
}
}
双缓冲队列:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* 测试双缓冲队列
* (1)首先,使用ArrayBlockingQueue类创建一个大小为10的双缓冲队列
* queue;然后,循环20次向队列queue中添加元素,如果5秒内元素仍没有入队
* 到队列中,则返回false。
* (2)首先,使用ArrayBlockingQueue类创建一个大小为10的双缓冲队列
* queue;然后,将0到9,10个数字加入到队列queue中;最后,循环20次从
* 队列queue中取元素,如果5秒内元素仍没有入队,则返回null。
* @author wangyu
*/
public class testBlockingQueue {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
testBlockingQueue tbq = new testBlockingQueue();
// tbq.testOffer();
tbq.testPull();
}
/**
* 测试入队方法
*/
public void testOffer(){
BlockingQueue <Integer> queue = new ArrayBlockingQueue<Integer>(10);
for(int i = 0; i < 20; i++){
try {
boolean b = queue.offer(i,5,TimeUnit.SECONDS);
System.out.println("存入是否成功" + b);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 测试出队方法
*/
public void testPull(){
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10);
for(int i = 0; i < 20; i++){
queue.offer(i);
}
for(int i = 0;i < 20; i++){
//获取元素,设置5秒超时,5秒内还没有元素可取回则返回null
try {
Integer num= queue.poll(5, TimeUnit.SECONDS);
System.out.println("元素" + num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
面试题:
子线程循环10次,接着主线程循环100,接着又子线程循环10次,接着又主线程循环100,如此50次。写出代码:
/**
* 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。
* @author lijinnan
* @date:2013-11-5 下午3:07:10
*/
public class ThreadComunication {
private static final int ROUND_COUNT = 50;
public static void main(String[] args) {
//主线程和子线程“共享”一个Busines实例
final Business business = new Business();
/*
//主线程
for (int i = 0; i < ROUND_COUNT; i++) {
business.main(i);
}
*/
//子线程-注意要先启动子线程,否则子线程不会启动,主线程在roundIndex=0执行完毕后就陷入无限等待
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < ROUND_COUNT; i++) {
business.sub(i);
}
}
}).start();
//主线程
for (int i = 0; i < ROUND_COUNT; i++) {
business.main(i);
}
}
}
class Business {
private static final int SUB_COUNT = 10;
private static final int MAIN_COUNT = 100;
private boolean doSub;
public synchronized void sub(int roundIndex) {
while (!doSub) {
try {
wait();
} catch (InterruptedException e) {
//ignore
}
}
for (int i = 0; i < SUB_COUNT; i++) {
System.out.println("sub " + i + " of " + roundIndex);
}
doSub = false;
notifyAll();
}
public synchronized void main(int roundIndex) {
while (doSub) {
try {
wait();
} catch (InterruptedException e) {
//ignore
}
}
for (int i = 0; i < MAIN_COUNT; i++) {
System.out.println("main " + i + " of " + roundIndex);
}
doSub = true;
notifyAll();
}
}